![](/img/trans.png)
[英]Inserting C code between YACC grammar's rules creates shift/reduces conflicts
[英]lvalue grammar in yacc reduces incorrectly
我正在尝试使用YACC解析多维数组。 这是我的左值定义:
lvalue: ID { EM_debug("got lvalue identifier " + to_String($1));
$$.My_VAR = A_SimpleVar($$.pos, $1);
$$.size = 0;
$$.name = $1;
}
| lvalue L_SQUARE_BRACKET exp R_SQUARE_BRACKET { EM_debug("got lvalue[exp]");
$$.My_VAR = A_SubscriptVar($$.pos, $1.My_VAR, $3.My_AST);
$$.size = $3.My_AST;
$$.name = $1.name;
}
;
对于(简化的)输入ia[2]
它打印got lvalue identifier ia
并在遇到左括号时给出解析错误。 我不明白为什么这不起作用。 它应该在前瞻和左移中看到左括号。 它不应该像这样立即减少。 我怎样才能阻止它移动?
不要将YACC用于lval与rval区分。 因为lval也几乎总是rval,它会在语法中创建减少/减少冲突,这使得它不确定。
使用语义分析阶段检查lval正确性,而不是将其合并到YACC语法中。
但是作为参考,GNU Bison通过减少文件中首先定义的规则来处理减少/减少冲突。 这可能会帮助您暂时解决问题。
相反,减少是完全正确的。 为了申请
lvalue: lvalue L_SQUARE_BRACKET exp R_SQUARE_BRACKET
对输入
ia[2]
在转移[ (假设L_SQUARE_BRACKET
是[ ,见下文))之前,解析器需要将ia
变为lvalue
。 它通过使用规则lvalue: ID
来实现这一点,因此我们可以期望该规则在[被移位之前]运行。
所以这不是问题,问题中没有足够的信息来提供更好的诊断。 然而,为了它的价值,一些注意事项:
1)就个人而言,我发现在野牛规则中使用文字字符更不容易出错且更容易阅读:
lvalue: lvalue '[' exp ']'
当然需要与返回文字字符的flex规则匹配:
"["|"]" { return *yytext; }
(或者,使用可能不太可读的语法: [][]
可以扩展到更长的单个字符标记列表,例如[][(){}<>=+*/-]
:只记住]
必须先来,然后-
最后一个角色类)。
扫描仪和解析器之间完全不匹配会导致[
没有使用正确的令牌类型发送; 你当然需要消除调试的可能性。
2)野牛是否告诉你任何冲突(包括轮班减少冲突)? 需要追踪和消除这些中的每一个。
3)你怎么知道的,当正在生成语法错误[
被视为? 例如,您是否启用了flex调试跟踪(非常方便调试)和/或bison调试跟踪(我认为这比在您的操作中散布打印语句更有用,但是YMMV)?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.