首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >GPPG-语法-永远不会使用的规则

GPPG-语法-永远不会使用的规则
EN

Stack Overflow用户
提问于 2016-04-07 21:54:32
回答 1查看 125关注 0票数 1

我的一些语法规则有问题。

语法如下:

代码语言:javascript
复制
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
         ;

使用要检查的输入:

代码语言:javascript
复制
DEF INT testvar1
DEF REAL testvar2

对于这一输入,应该使用头为"defLine“的第二条规则。

为什么不是呢?第三条规则将始终使用,并抛出错误

代码语言:javascript
复制
Unexpected 'carRet', '[' expected.

非常感谢你的帮助,亚历克斯

EN

回答 1

Stack Overflow用户

发布于 2016-04-08 00:27:53

该语法肯定会产生至少一个shift/reduce冲突,并警告说,由于冲突,生产attrbt: /* nothing */是无用的。(如果不是这样,那是因为GPPG没有提供像野牛那样多的警告。但我确信,它至少会标志着这种转变/减少冲突。)

冲突出现在规则中:

代码语言:javascript
复制
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的空生产,并显式允许它丢失:

代码语言:javascript
复制
attrbt   : "PHU" intValue

defLine  : "DEF" kwType ID
         | "DEF" kwType attrbt ID
         | "DEF" kwType ID fieldSuff
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36478345

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档