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 规范中的单引号标记不对应的字符都会在解析器中触发语法错误。
我不知道怎么说,因为 "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 规范中的单引号标记不对应的字符都会在解析器中触发语法错误。