flex/bison: '$' 操作数给出 large/wrong 文本块

flex/bison: '$' operand giving large/wrong chunks of text

我不知道怎么说,因为 "addressing" 似乎指的是 lines/columns 的“%”操作数和规范,这不是我要找的。我想弄清楚“$”符号究竟是如何工作的。另外我不知道这些是操作数还是它们是什么,如果你能告诉我,请告诉我,如果不是,请避免关注我所说的它们,并强调告诉我“$”是做什么的。 我在野牛中有这个相当长的表达:

for: KW_FOR S_PARENTHESIS_OPEN assignment S_SEMICOLON gen_ex S_SEMICOLON assignment S_PARENTHESIS_CLOSE command_block 
{
printf("condition: %s", );
};

(注意任何大写字母都是直接对应word/symbol的token) 输入是:

void myProgram ()
BEGIN
x = 1;
if( x < 3 ) x = 2;

if(x > 3) x = 3; else x = 2;

while (x < 2)
BEGIN
y = 2;
END

for ( x = 1; y < 3; z = 2)
BEGIN
z = 4;
END

END

如果我要求 </code>,我原以为 printf() 会给我 <code>for 关键字,但它实际上是从前一个 "while" 中的 y = 2 开始的] 循环,我无法理解,因为它超出了表达式的范围。

那么,这究竟应该如何决定我所做的参考在哪里?既然我们在这里,那这到底叫什么?

编辑: 我知道我写了 3 美元,这行得通。如果我写 $1 它不会按预期工作。我在问这些东西叫什么,野牛如何决定第一个符号是什么,因此如果我要 1 美元,它为什么会给我特定表达式之前的东西。这就是我想知道的,以及如何正确引用这些东西。

$n指的是nth符号的语义值在当前制作的右侧。

终端的语义值是 return 编辑终端代码的扫描器规则分配给 yylval 的任何值。如果 flex 动作没有给 yylval 分配任何东西,就没有语义值(或者,更准确地说,语义值是未初始化的,引用它是 未定义的行为 ).

非终结符的语义值是解析器 (bison) 操作分配给 $$ 的任何值。如果没有与产生式关联的动作,或者如果该动作未将任何内容分配给 $$,则非终结符的语义值将从 </code>(在该产生式中)复制。在那种情况下,如果 <code> 没有语义值,那么相应的非终结符也没有,并且再次尝试使用该值是 未定义的行为

语义值的(C)类型为YYSTYPE,默认为int,您可以在序言中设置。或者您可以将其定义为 union type —— 即普通 C union —— 在这种情况下,bison 需要知道哪个 union 成员适用于每个终端,并且非终端。在这种情况下,扫描器需要分配给 yylval.

的正确成员

我强烈建议您阅读 bison manual. You could skip to the section on semantics,但如果您刚开始,您会发现从头开始阅读很有用,尤其要注意示例。

祝你好运。


一个简单的建议:不要用 S_PARENTHESIS_OPEN 之类的东西填满你的语法。这无助于提高可读性或效率或任何东西。更好的风格是使用单引号字符作为单字符标记,并为较长的标记定义双引号别名:

 /* It is not necessary to declare single-quoted character tokens */
%token KW_FOR "for"
%%
 /* Example: */
for: "for" '(' assignment ';' gen_ex ';'  assignment ')' command_block

在您的扫描仪中,您 return 单字符标记的实际字符;较长的标记需要使用在 %token 行中声明的符号名称:

"for"     { return KW_FOR; }
[();]     { return yytext[0]; }

上面的第二条弹性规则阐明了可能的单字符标记,但在弹性规则末尾使用后备规则会更容易:

.          { return yytext[0]; }

因为任何与您的 bison 规范中的单引号标记不对应的字符都会在解析器中触发语法错误。