Frage

Wikipedias Interpolation Definition Ich lerne gerade flex / Bison und ich mit ihm meine eigene Schale schreibe. Ich versuche, einen guten Weg, um herauszufinden, variable Interpolation zu tun. Mein erster Ansatz dazu war wie ~ etwas Flexscan hat für mein Home-Verzeichnis oder $ myVar und dann festzulegen, was die yyval.stringto was eine Suchfunktion zurückgegeben werden. Mein Problem ist, dass dies hilft mir nicht, wenn Text einen Token erscheint:

kbsh:/home/kbrandt% echo ~
/home/kbrandt
kbsh:/home/kbrandt% echo ~/foo
/home/kbrandt /foo
kbsh:/home/kbrandt%

Die lex Definition Ich habe für Variablen:

\$[a-zA-Z/0-9_]+    {
    yylval.string=return_value(&variables, (yytext + sizeof(char)));;
    return(WORD);
}

Dann in meiner Grammatik, ich habe Dinge wie:

chdir_command:
    CD WORD { change_dir($2); }
    ;

Wer weiß, eine gute Möglichkeit, diese Art der Sache zu behandeln? Bin ich über dieses alles falsch gehen?

War es hilfreich?

Lösung

Die Art und Weise ‚traditionelle‘ Schalen mit Dingen wie Variablensubstitution behandeln ist schwierig, mit lex / yacc zu behandeln. Was sie tun, ist eher wie Makroerweiterung, wo nach einer variablen erweitern, sie dann die Eingabe erneut tokenize, ohne weitere Variablen zu erweitern. So zum Beispiel eine Eingabe wie „xx $ {$ foo}“, wo ‚foo‘ als ‚bar‘ definiert und ‚bar‘ ist definiert als ‚$ y‘ wird zu ‚xx $ y‘ erweitern, die als ein behandelt werden Wort (und $ y wird nicht erweitert werden).

Sie können mit diesem in flex umgehen, aber man braucht eine Menge Code zu unterstützen. Sie müssen flex yy_buffer_state Sachen verwenden manchmal die Ausgabe in einen Puffer leiten, die Sie dann von Rescan werden, und verwenden Staaten sorgfältig beginnen, wenn die Steuervariablen können und nicht erweitert werden kann.

Es ist wahrscheinlich einfacher, eine sehr einfache Lexer zu verwenden, die Token wie ALPHA (ein oder mehr alphabetische Zeichen), Numerisch (eine oder mehr Ziffern) oder Leerzeichen (ein oder mehr Leerzeichen oder Tab) gibt, und hat den Parser sie zusammenbauen in geeigneter Weise, und Sie am Ende mit Regeln wie:

simple_command: wordlist NEWLINE ;

wordlist: word | wordlist WHITESPACE word ;

word: word_frag
    | word word_frag { $$ = concat_string($1, $2); }
;

word_frag: single_quote_string
         | double_quote_string
         | variable
         | ALPHA
         | NUMERIC
        ...more options...
;

variable: '$' name { $$ = lookup($2); }
        | '$' '{' word '}' { $$ = lookup($3); }
        | '$' '{' word ':' ....

Wie Sie sehen können, diese recht schnell komplex werden.

Andere Tipps

Sieht allgemein OK


Ich bin mir nicht sicher, was return_value tut, wird es hoffentlich die Variablennamen strdup(3), weil yytext nur ein Puffer ist.

Wenn Sie über die Arbeitsteilung zwischen lex fragen und analysieren, ich bin sicher, dass es durchaus sinnvoll, die Makroverarbeitung und Parametersubstitution in den Scanner schieben und müssen nur Ihre Grammatik befassen sich mit WORDs, Listen, Befehle, Pipelines, Umleitungen usw. Schließlich wäre es genug, wenn auch Art von Stil und möglicherweise dem Sieg über den Punkt Ihrer Übung, alles zu tun, mit dem Code angemessen sein.

Ich glaube, dass cd machen oder ein Terminal-Symbol chdir und die Verwendung dieser in einer Grammatik Produktion ist ... nicht die beste Design-Entscheidung. Nur weil ein Befehl eine eingebaute, ist, bedeutet nicht, dass es in der Regel erscheinen soll. Gehen Sie weiter und analysieren cd und chdir wie jeder andere Befehl. Überprüfen Sie für Einbau-Semantik als eine Aktion, keine Produktion.

Nach allem, was ist, wenn es als eine Shell-Prozedur neu definiert wird?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top