0

我正在研究解析器,我真的很沮丧。在语言中,我们可以有这样的表达式:

new int[3][][]

或者

new int[3]

除了最后的空数组外,大部分都正确解析。在我的解析器中,我有:

Expression : int
             char
             null
             (...many others...)
             new NewExpression

然后一个 NewExpression 是:

NewExpression : NonArrayType '[' Expression ']' EmptyArrays
              | NonArrayType '[' Expression ']' 

然后 EmptyArrays 是一个或多个空大括号 - 如果 EmptyArrays 派生出空字符串,它会添加 20 个移位/减少冲突:

EmptyArrays : EmptyArrays EmptyArray
            | EmptyArray
EmptyArray  : '[' ']'

但是,当我在.info文件中查找解析器时,我得到了这个:

State 214¬
¬
▸   NewExpression -> NonArrayType lbrace Expression rbrace . EmptyArrays    (rule 80)¬
▸   NewExpression -> NonArrayType lbrace Expression rbrace .    (rule 81)¬
¬
▸   dot            reduce using rule 81¬
▸   ';'            reduce using rule 81¬
▸   ','            reduce using rule 81¬
▸   '+'            reduce using rule 81¬
▸   '-'            reduce using rule 81¬
▸   '*'            reduce using rule 81¬
▸   '/'            reduce using rule 81¬
▸   '<'            reduce using rule 81¬
▸   '>'            reduce using rule 81¬
▸   '<='           reduce using rule 81¬
▸   '>='           reduce using rule 81¬
▸   '=='           reduce using rule 81¬
▸   '!='           reduce using rule 81¬
▸   ')'            reduce using rule 81¬
▸   '['            reduce using rule 81    --I expect this should shift
▸   ']'            reduce using rule 81¬
▸   '?'            reduce using rule 81¬
▸   ':'            reduce using rule 81¬
▸   '&&'           reduce using rule 81¬
▸   '||'           reduce using rule 81

我希望如果我们处于状态 214 并且我们看到一个左大括号,我们应该将它移到堆栈上并继续解析 EmptyArrays。

我不完全确定发生了什么,因为当我通过以 开头的解析去除所有多余的行李(例如)时NewExpression,额外的括号会正确解析。表达式、语句或语法中的任何非终结符都不可能以左大括号开头。特别是因为我对 if/else 语句有类似的规则,它会产生移位/减少冲突,但如果下一个标记是 else 则选择移位(这个问题有据可查)。

你能帮我弄清楚出了什么问题吗?我真的很感谢你的帮助,我真的很喜欢风车试图找出问题所在。

4

1 回答 1

1

您可能为“[”和/或“]”设置了优先级,类似的东西%left '['会导致这种行为。删除该优先声明,这将揭示您在此处遇到的移位/减少冲突。至于为什么它是移位/减少冲突,您可能还有一个规则:

Expression: Expression '[' Expression ']'

用于数组访问。问题在于,由于 aNewExpression是 an Expression,它后面可能会跟着这样的索引,并且在查看 '[' 的前瞻时,它无法判断这是索引表达式的开始还是EmptyArray-的开始将需要 2 令牌前瞻。

对于这种特定情况,您可以尝试的一件事是让您的词法分析器执行此处所需的额外前瞻并将其识别[]为单个标记。

于 2011-02-21T03:40:47.683 回答