简体   繁体   English

yacc中的左值语法减少不正确

[英]lvalue grammar in yacc reduces incorrectly

I'm trying to parse multidimensional arrays with YACC. 我正在尝试使用YACC解析多维数组。 Here is my lvalue definition: 这是我的左值定义:

    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;
        }
    ;

For the (simplified) input ia[2] it prints got lvalue identifier ia and gives a parsing error when it encounters the left bracket. 对于(简化的)输入ia[2]它打印got lvalue identifier ia并在遇到左括号时给出解析错误。 I don't get why this would not work. 我不明白为什么这不起作用。 It should see the left bracket in its lookahead and shift. 它应该在前瞻和左移中看到左括号。 It should not reduce immediately like this. 它不应该像这样立即减少。 How can I prevent it from shifting? 我怎样才能阻止它移动?

Don't use YACC for lval vs. rval distinguishing. 不要将YACC用于lval与rval区分。 Because an lval is also almost always an rval, it creates reduce/reduce conflicts in the grammar and that makes it non-deterministic. 因为lval也几乎总是rval,它会在语法中创建减少/减少冲突,这使得它不确定。

Use a Semantic Analysis phase to check for lval correctness rather than incorporating it into the YACC grammar. 使用语义分析阶段检查lval正确性,而不是将其合并到YACC语法中。

For reference though, GNU Bison handles reduce/reduce conflicts by reducing by the rule which is defined first in the file. 但是作为参考,GNU Bison通过减少文件中首先定义的规则来处理减少/减少冲突。 So that might help you temporarily get around your problem. 这可能会帮助您暂时解决问题。

On the contrary, the reduction is completely correct. 相反,减少是完全正确的。 In order to apply 为了申请

lvalue: lvalue L_SQUARE_BRACKET exp R_SQUARE_BRACKET

to the input 对输入

ia[2]

the parser needs to make ia into an lvalue before shifting the [ (assuming that L_SQUARE_BRACKET is a [ , see below). 在转移[ (假设L_SQUARE_BRACKET[ ,见下文))之前,解析器需要将ia变为lvalue It does this by using the rule lvalue: ID , so we can expect that rule to run before the [ is shifted. 它通过使用规则lvalue: ID来实现这一点,因此我们可以期望该规则在[被移位之前]运行。

So that's not the problem, and there's not enough information in the question to provide a better diagnosis. 所以这不是问题,问题中没有足够的信息来提供更好的诊断。 However, for what it's worth, a few notes: 然而,为了它的价值,一些注意事项:

1) Personally, I find it much less error-prone and easier to read to use literal characters in bison rules: 1)就个人而言,我发现在野牛规则中使用文字字符更不容易出错且更容易阅读:

lvalue: lvalue '[' exp ']'

which of course needs to be matched with a flex rule which returns the literal characters: 当然需要与返回文字字符的flex规则匹配:

"["|"]"  { return *yytext; }

(or, using the possibly less readable syntax: [][] which can be extended to a longer list of single character tokens, such as [][(){}<>=+*/-] : just remember that ] must come first and - last in a character class). (或者,使用可能不太可读的语法: [][]可以扩展到更长的单个字符标记列表,例如[][(){}<>=+*/-] :只记住]必须先来,然后-最后一个角色类)。

It's entirely possible that there is a mismatch between your scanner and your parser which results in the [ not being sent with the correct token type; 扫描仪和解析器之间完全不匹配会导致[没有使用正确的令牌类型发送; you certainly need to eliminate that possibility for debugging. 你当然需要消除调试的可能性。

2) Is bison telling you about any conflicts (including shift-reduce conflicts)? 2)野牛是否告诉你任何冲突(包括轮班减少冲突)? Each of these needs to be tracked down and eliminated. 需要追踪和消除这些中的每一个。

3) How do you know that the syntax error is being generated when the [ is seen? 3)你怎么知道的,当正在生成语法错误[被视为? Have you, for example, enabled flex debugging traces (very handy for debugging) and/or bison debugging traces (which I find more useful than scattering print statements in your actions, but YMMV)? 例如,您是否启用了flex调试跟踪(非常方便调试)和/或bison调试跟踪(我认为这比在您的操作中散布打印语句更有用,但是YMMV)?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM