我有一些令人困惑的问题让我在循环中运行,请帮助我理解它们。
如果我有两个文件,则.y
是解析器文件,第二个是.l
词法分析器
我可以在解析器文件中使用yytext
,我是否应该定义yylex
使用它?
如果我想在声明部分的解析器文件中声明它,我想要更改它吗?
如果在lex文件中我将一个令牌返回给解析器,如下所示:
[0-9]返回DIGIT; 什么传递给解析器DIGIT与找到的数字或只有数字本身没有DIGIT?
如何在解析器文件中使用yyerror
,因为我需要解析器使用yylineno
并告诉错误发生在哪里以及导致错误的是什么?
:
exp - > exp | / 为空 /
与
相同yylineno
我很感激能帮助我解决这些问题的人,因为他们让我很困惑,提前谢谢
答案 0 :(得分:1)
在yytext
文件中使用.y
是危险且容易出错的 - 如果yytext
是数组或指针,它的定义不明确,甚至可能不均匀在.l
文件外部可见。
在liby.a中定义了yyerror
函数 - 如果您与-ly
链接,它将可供您使用。如果您想定义自己的yyerror
,可以在任何地方进行定义。
return DIGIT;
将返回DIGIT
作为令牌(可能是.y
文件中%token
定义的令牌,与实际数字无关如果要访问解析器中的数字值,则需要将其从词法分析器中的yytext
复制到yylval
:
[0-9] { yylval = *yytext-'0'; return DIGIT; }
yylineno
,如果它存在(需要正确的flex选项让它自动创建)通常只是一个全局变量。您需要注意的是,解析器可能会在缩小规则之前提前读取令牌,因此{1}可能会被一个令牌关闭到您真正想要的位置。如果您正在使用bison,则可以在重新调整每个令牌之前将词法分析器yylineno
复制到yylineno
,这样您就可以为解析器中的每个令牌获取正确的行号。
以下各项完全相同:
yylloc
exp: exp | /*empty */ ;
exp: /*empty*/ | exp ;
一般来说,exp: /*empty*/ ;
exp: exp ;
文件中的规则顺序无关紧要(它会影响减少/减少冲突的解决方案,但不会影响其他内容)。
请注意,像.y
这样的规则会自动使您的语法模糊不清并导致转移/减少冲突。