我的一些语法规则有问题。
语法如下:
defLINES : carrRet
| defLine carrRet
| defLines defLine carrRet
;
defLine : error carrRet {yyerrok();}
| "DEF" kwType attrbt ID
| "DEF" kwType ID fieldSuff
;
kwType : "INT"
| "REAL"
;
fieldSuff: "[" expr "]"
| "[" expr "," expr "]"
;
attrbt : /* nothing */
| "PHU" intValue
;使用要检查的输入:
DEF INT testvar1
DEF REAL testvar2对于这一输入,应该使用头为"defLine“的第二条规则。
为什么不是呢?第三条规则将始终使用,并抛出错误
Unexpected 'carRet', '[' expected.非常感谢你的帮助,亚历克斯
发布于 2016-04-08 00:27:53
该语法肯定会产生至少一个shift/reduce冲突,并警告说,由于冲突,生产attrbt: /* nothing */是无用的。(如果不是这样,那是因为GPPG没有提供像野牛那样多的警告。但我确信,它至少会标志着这种转变/减少冲突。)
冲突出现在规则中:
defLine : "DEF" kwType attrbt ID
defLine : "DEF" kwType ID fieldSuff因为在第二个规则中,attrbt可以为空,但不能在ID之前。假设解析器遇到了DEF INT,下一个符号是ID。在这一点上,解析器不知道defLine使用这两个结果中的哪一个,但是区别很重要。在第一种情况下,解析器必须在移动attrbt之前减少一个空ID。在第二种情况下,创建attrbt将是一个错误。
类似Yacc的解析器生成器总是为了支持移位而解决移位/归约冲突(除非有优先级声明),所以在这种情况下,ID将始终被移位。这意味着降低生产attrbt: /* nothing */是不可能的。(野牛至少会警告你这个事实。
此外,由于在这种情况下将发生ID的转换,因此只有defLine的第二个结果可用,因此解析器将要求fieldStuff跟随ID,并且fieldStuff必须以[开头。因此,您会遇到解析错误。
要解决此问题,您需要删除shift/reduce冲突。一种简单的方法是在两个defLine产品中都允许attrbt (您可以检测语义操作中的错误)。另一种可能性是删除attrbt的空生产,并显式允许它丢失:
attrbt : "PHU" intValue
defLine : "DEF" kwType ID
| "DEF" kwType attrbt ID
| "DEF" kwType ID fieldSuffhttps://stackoverflow.com/questions/36478345
复制相似问题