2

インタープリターを作成しようとしていますが、プロセスの理論的基盤を理解するのに苦労しています。

最初の部分は、文字列を有効なトークンのリストに分割するレクサーを記述し、次にパーサーを使用して、このトークンの文字列に対応する抽象構文ツリーを生成することであることを理解しています。ただし、パーサーは文法規則を使用して構築されているため、理解が困難です。

結果の抽象構文ツリーのルールを作成するために文法ルールが使用されることは明らかですが、この中間ステップはどのように機能するのでしょうか。文字列文字とトークンの特定のリストまたは . . .?

どんな種類の直感や説明も歓迎します。ありがとう!

4

1 に答える 1

1

インターネットで lex/yacc の例とチュートリアルを検索してください。実践的学習。Cでプログラミングできる能力も必要です。

http://ds9a.nl/lex-yacc/cvs/lex-yacc-howto.html

lex は古い Unix lexer であり、正規表現ベースの仕様から C コードを生成します。yacc は、構文ツリーを構築するための古代の Unix パーサーです。Cコードも生成します。

ツールの最新の GNU バージョンは、flex および bison と呼ばれます。

電卓の yacc コードのコアは次のとおりです。トークンからより高いレベルの構成がどのように構築されるか、およびそのような構成に遭遇したときに何をすべきかを示します。

%%
list : // empty
     | list stm '\n'         { print(); }
     | list cmd '\n'         { print(); }
     | list cmd stm '\n'     { print(); }
     | list stm cmd '\n'     { print(); }
     | list cmd stm cmd '\n' { print(); }
     | list error '\n'       { yyerrok; print(); }
     ;
cmd  : COMMAND               { commands[$1](); }
     ;
stm  : expr                  { output = $1; outputPush(); }
     | VAR '=' expr          { vars_set($1, &$3); }
     ;
expr :                       { outputGet(); $$ = output; }
     | '_'                   { outputGet(); $$ = output; }
     | '(' expr ')'          { $$ = $2; }
     | expr OPADD expr       { $$ = tNumOpIn ($1, $2, $3); }
     | expr OPMUL expr       { $$ = tNumOpIn ($1, $2, $3); }
     | expr OPPOW expr       { $$ = tNumOpIn ($1, $2, $3); }
     | OPPRE expr            { $$ = tNumOpPre($1, $2); }
     | VAR                   { if (vars_get($1,&$$)) $$=output; }
     | NUMBER                { $$ = $1; }
     ;
%%  
于 2014-02-24T16:29:19.877 に答える