我正在尝试编写口译员,但难以理解该过程的理论基础。
我知道,第一部分是编写一个词法分析器,该词法分析器将字符串分成有效令牌的列表,然后使用解析器为该令牌字符串生成相应的抽象语法树。但是,解析器是使用语法规则构建的,这是我很难理解的。
显然,可以使用语法规则来创建结果抽象语法树的规则,但是该中间步骤的工作原理是什么。它与字符串字符和特定的标记或列表匹配吗?。。?
欢迎任何类型的直觉或解释。谢谢!
在互联网上搜索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; }
;
%%
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句