J'ai fait un peu/beaucoup d'expériences, et ce qui semble être les principaux résultats.
Afin de mieux comprendre comment des lots de travaux, et pourquoi parfois échapper à des œuvres et à d'autres moments, il semble échouer.
- Je faire ce travail par de nombreuses expériences, et j'essais de construction afin que je puisse identifier l'ordre des phases.
Il existe de multiples domaines à examiner.
J'ai eu l'
- BatchLineParser - Le à l'intérieur de l'analyseur de fichiers par lots, pour les lignes ou blocs
- CmdLineParser - Comme le BatchLineParser, mais directement à l'invite de commandes, travaux de différents
- LabelParser - Comment appeler/goto et les étiquettes de travail
- CommandBlockCaching - Comment parenthèse et la mise en cache fonctionne
- Générateur de jetons - Faire unique des jetons(groupes de personnages) construire et dans laquelle les phases
Le BatchLineParser:
Une ligne de code dans un fichier de commandes a plusieurs phases (sur la ligne de commande de l'expansion est différente!).
Le processus commence avec la phase 1
Phase/commande
1) Phase(En Pourcentage):
- Un double -
%%
est remplacé par un simple %
- L'Expansion de l'argument des variables (
%1
, %2
, etc.)
- L'Expansion de l'
%var%
, si var n'existe pas remplacer par rien
- Pour une explication complète lisez ceci du dbenham Même thread: pourcentage de l'expansion
1.5) Supprimer tous <CR>
(CarriageReturn 0x0d) de la ligne
2) Phase(caractères Spéciaux, "
<LF>
^
&
|
<
>
(
)
: Regarder chaque personnage
- Si c'est une citation (
"
) bascule la citation drapeau, si le devis drapeau est active, les caractères spéciaux suivants ne sont plus spécial: ^
&
|
<
>
(
)
.
- Si c'est un signe (
^
) le prochain personnage n'a pas de signification particulière, le signe lui-même est supprimée, si le signe est le dernier caractère de la ligne, la ligne suivante est ajoutée, le premier personnage de la ligne suivante est toujours traitée comme évadé personnage.
-
<LF>
s'arrête le traitement immédiatement, mais pas avec un curseur en face
- Si c'est l'un des caractères spéciaux
&
|
<
>
séparer la ligne à ce point, dans le cas de la conduite (|
) les deux parties obtient une phase de redémarrage (un peu plus complexe ...) Pour plus d'informations sur la façon dont les tuyaux sont analysées et traitées, regardez cette question et réponses: Pourquoi expansion retardée d'échouer lorsqu'à l'intérieur d'une canalisation d'eau bloc de code?
- Dans cette phase, le jeton principal de la liste est en construction, les séparateurs de jetons sont
<space>
<tab>
,
;
=
et <0xFF>
(aussi connu comme l'espace insécable)
- Processus de parenthèse (composé instructions sur plusieurs lignes):
- Si l'analyseur n'est pas la recherche d'un jeton de commande, puis
(
n'est pas spécial.
- Si l'analyseur est à la recherche d'un jeton de commande et trouve
(
, puis de lancer un nouveau composé de déclaration et d'incrément de la parenthèse compteur
- Si la parenthèse compteur est > 0 alors
)
met fin à l'instruction composée et décrémente la parenthèse compteur.
- Si l'extrémité de la ligne est atteint et que la parenthèse compteur est > 0 alors la ligne suivante sera annexé à l'instruction composée (commence de nouveau à la phase 1)
- Si la parenthèse compteur = 0, et l'analyseur est à la recherche d'une commande, alors
)
et tous les caractères restants sur la ligne sont ignorés
- Dans cette phase REM, SI et sont détectés, pour la gestion spéciale d'entre eux.
- Si le premier élément est "
rem
", seulement deux jetons sont traitées, important pour le multiligne signe
3) Phase(echo): Si "l'écho est sur" imprimer le résultat de la phase 1 et 2
- Pour-boucle-blocs sont fait l'écho à plusieurs reprises, la première fois dans le contexte de la boucle for, avec non développés pour-boucle-vars
- Pour chaque itération, le bloc est fait l'écho avec élargis à-boucle-vars
---- Ces deux phases ne sont pas vraiment la suite directe, mais il ne fait aucune différence
4) Phase(à-boucle-vars expansion): l'Expansion de l' %%a
et ainsi de suite
5) Phase(point d'Exclamation): Seulement si l'expansion retardée est sur, regardez chaque personnage
- Si c'est un signe (
^
) le prochain personnage n'a pas de signification particulière, le signe lui-même est supprimé
- Si il est un point d'exclamation, recherche pour le prochain point d'exclamation (signes ne sont pas observées plus), développez le contenu de la variable
- Consécutives de l'ouverture d'
!
sont fusionnés en un seul !
- Tout en restant
!
qui ne peuvent pas être associé est supprimé
- Si aucun point d'exclamation se trouve dans cette phase, le résultat est ignoré, le résultat de la phase 4 est utilisé à la place (importante pour les carets)
- Important: Lors de cette phase de citations et d'autres spéciques caractères sont ignorés
- L'expansion de vars, à ce stade, est "safe", parce que les caractères spéciaux ne sont pas détectés plus (même
<CR>
ou <LF>
)
6) Phase(appel/caret doublement): Uniquement si le cmd jeton est de les APPELER
- Si le premier élément est "
call
", de commencer avec la phase 1 de nouveau, mais s'arrête après la phase 2, l'expansion retardée ne sont pas traitées une deuxième fois ici
- Supprimer le premier
CALL
, de sorte que plusieurs APPELS peuvent être empilés
- Double tous les carets (normal carets semble rester inchangé, parce que, dans la phase 2, ils sont réduits à un seul, mais dans les citations qu'ils sont effectivly doublé)
7) Phase(Exécuter): La commande est exécutée
- Jetons différents sont utilisés ici, dépend de l'organisation interne de la commande exécutée
- Dans le cas d'un
set "name=content"
, le contenu complet de la première signe égal à la dernière citation de la ligne est utilisée en tant que contenu-jeton, si il n'y a pas de citation après le signe égal, le reste de la ligne est utilisée.
CmdLineParser:
Des œuvres comme la BatchLine-Parser, mais:
- Goto/appel d'une étiquette n'est pas autorisé
Phase1(En Pourcentage):
- %var% sera remplacé par le contenu de var, si la var n'est pas défini, l'expresssion sera inchangé
- Pas de traitement particulier de % de % de, la seconde pour cent pourrait être le début d'une var, set var=contenu, %%var%% étend à l' %Contenu%
Phase5(point d'exclamation): uniquement si "DelayedExpansion" est activée
- !var! sera remplacé par le contenu de var, si la var n'est pas défini, l'expresssion sera inchangé
pour la boucle de commande de bloc
par exemple, for /F "usebackq" %%a IN (
commande bloc) DO echo %%a
Le bloc de commandes sera analysée en deux temps, d'abord le BatchLineParser(la boucle est à l'intérieur d'un lot) ou le CmdLineParser(boucle sur le cmd-line) est active, lors de la deuxième manche, toujours le CmdLineParser est active.
Dans la deuxième manche, DelayedExpansion est active que si elle est activé avec la clé de registre
La deuxième manche est comme appeler la ligne avec cmd /c
Détermination des variables ne sont donc pas persistant.
J'espère que ça aide
Jan Erik