flex/bison:'$';提供大/错误文本块的操作数

flex/bison:'$';提供大/错误文本块的操作数,bison,yacc,Bison,Yacc,我不知道该怎么说,因为“寻址”似乎指的是“%”操作数和行/列的规格,这不是我想要的。我试图弄清楚“$”符号到底是如何工作的。此外,我不知道这些是操作数还是它们是什么,如果你能告诉我,请这样做,如果不是,请避免关注我称之为它们的内容,并强调告诉我“$”的作用。 我在《野牛》中有一个相当长的表达: for: KW_FOR S_PARENTHESIS_OPEN assignment S_SEMICOLON gen_ex S_SEMICOLON assignment S_PARENTHESIS_CLOS

我不知道该怎么说,因为“寻址”似乎指的是“%”操作数和行/列的规格,这不是我想要的。我试图弄清楚“$”符号到底是如何工作的。此外,我不知道这些是操作数还是它们是什么,如果你能告诉我,请这样做,如果不是,请避免关注我称之为它们的内容,并强调告诉我“$”的作用。 我在《野牛》中有一个相当长的表达:

for: KW_FOR S_PARENTHESIS_OPEN assignment S_SEMICOLON gen_ex S_SEMICOLON assignment S_PARENTHESIS_CLOSE command_block 
{
printf("condition: %s", $3);
};
(请注意,任何大写字母都是直接对应于单词/符号的标记) 输入为:

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
void myProgram()
开始
x=1;
如果(x<3)x=2;
如果(x>3)x=3;否则x=2;
而(x<2)
开始
y=2;
结束
对于(x=1;y<3;z=2)
开始
z=4;
结束
结束
如果我要求
$1
,我希望printf()会给我
for
关键字,但它实际上是从上一个“while”循环中的
y=2
开始的,因为它超出了表达式的范围,所以我无法理解

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


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

$n
是指当前产品右侧第n个符号的语义值

终端的语义值是由返回终端代码的扫描器规则分配给
yylval
的任何值。如果flex操作没有将任何内容分配给
yylval
,则没有语义值(或者更准确地说,语义值未初始化,引用它是未定义的行为)

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

语义值的(C)类型默认为
YYSTYPE
,可以在序言中设置。或者您可以将其定义为联合类型——也就是说,普通的C
联合
——在这种情况下,bison需要知道哪个联合成员适用于每个终端和非终端。在这种情况下,扫描仪需要分配给
yylval
的正确成员

我强烈建议你读这本书。您可以跳到上一节,但如果您刚刚开始,您会发现从头开始阅读非常有用,特别注意示例

祝你好运


一个快速的建议:不要用
S\u括号\u OPEN
之类的东西填满你的语法。这无助于提高可读性或效率。更好的样式是为单字符标记使用单引号字符,并为较长的标记定义双引号别名:

 /* It is not necessary to declare single-quoted character tokens */
%token KW_FOR "for"
%%
 /* Example: */
for: "for" '(' assignment ';' gen_ex ';'  assignment ')' command_block
在扫描仪中,返回单字符标记的实际字符;较长的令牌需要使用
%token
行中声明的符号名:

"for"     { return KW_FOR; }
[();]     { return yytext[0]; }
上面的第二条flex规则详细说明了可能的单字符标记,但在flex规则末尾使用回退规则更容易:

.          { return yytext[0]; }

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

$
不是操作数<代码>生产中的$3指的是
分配
$1
指的是右侧的第一个符号,但不清楚您为什么需要访问
for
关键字。这里没有“
%
操作数”。不清楚你在问什么。我真的不需要访问,这是一个测试,看看它会显示什么,我非常惊讶它既没有显示第一个非关键字符号,也没有显示一般的第一个符号<代码>$3工作正常,但我想知道为什么
$1
也不能像我预期的那样工作,我甚至可以如何查找“$”这个东西,它的名称。我知道没有“
%
操作数”,但当我查找地址作为最合理的命名时,我得到的结果就是这样。你没有抓住重点,我知道我错了,试图弄清楚什么叫什么,它是如何工作的你没有抓住重点。这里没有“
%
操作数”,您对其含义的解释只会增加混淆。你需要做的是发布你遇到的实际问题。当你试图解决它的时候,没有遇到很多其他的事情。没有理由认为,
$1
应该向您提供关键字的文本,除非您已经以这种方式编程了所有内容,如果这是您所期望的,这并不清楚,并且如果这是您真正需要的,这不是。我提到“%operand”只是为了表明,如果我查找“address”,这就是我在结果中得到的结果。我不在乎那个符号,这就是为什么它不在我的代码中。现在,如果我想检查“for”关键字,那是我的事,也是我的精神问题。假设我真的想修改它,如果它有帮助的话。我相信很明显,我想知道为什么我没有把“for”打印出来,但我得到的东西超出了表达的范围。我正在尽最大努力缩小编辑问题的范围,具体说明我关心什么和不关心什么。太棒了,我修改了代码,使之成为
yylval=yytext用于任何非数字的内容