首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >BNFC简单生产规则的解析问题

BNFC简单生产规则的解析问题
EN

Stack Overflow用户
提问于 2019-04-11 10:32:19
回答 1查看 112关注 0票数 0

这是我的BNFC格式语法的简化版本:

代码语言:javascript
复制
-- programs -------------------------------------
entrypoints Program ;
Prog.           Program ::= [ Def ] ;
terminator      Def "" ;


-- definitions ----------------------------------
DVar.           Def ::= VarDecl ;
DFun.           Def ::= FunDef;

-- functions definitions ------------------------
DFunAll.        FunDef ::= FunType Id "(" [ Arg ] ")" FunBody;
DFunBody.       FunBody ::= "{" RetStmt "}" ;

-- function statements --------------------------
StmtRetVoid.    RetStmt ::= "return" ";" ;

-- variable declarations ------------------------
DVarSimple.     VarDecl ::= Type Id ";" ;
DVarList.       VarDecl ::= Type Id "," [Id] ";" ;

-- arguments ------------------------------------
ArgDecl.        Arg ::= Type Id ;
separator       Arg "," ;

-- types -----------------------------------------
TInt.           Type ::= "int" ;
TFunRetT.       FunType ::= Type ;
TFunRetV.       FunType ::= "void" ;

-- identifiers ------------------------------------
position token  Id (letter (letter | digit | '_')*) ;
separator       Id "," ;

对于这种语法,happy生成1个未使用的规则和1个shift/reduce冲突警告。这里我面临的问题是,我不能正确地解析返回类型的函数。闻起来很简单,但我被卡住了。

更确切地说,当int foo(int x) {return;}成功解析时,我得到了void foo(int x) {return;}的解析错误。因此,这三条规则似乎不像设想的那样一起工作:

代码语言:javascript
复制
DFunAll.        FunDef ::= FunType Id "(" [ Arg ] ")" FunBody;
TInt.           Type ::= "int" ;
TFunRetT.       FunType ::= Type ;

如果我将FunDef规则更改为FunDef ::= Type Id "(" [ Arg ] ")" FunBody;,解析进行得很顺利,但我希望保持TypeFunType的区别,以免void成为常规的Type

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-04-12 02:42:40

我想保持TypeFunType的区别,这样就不会像普通Type那样无效了。

但是,您要求解析器在有足够的信息作出决定之前决定intType还是FunType。由于无法判断是否应用生产FunType ::= Type,所以它选择转移Id (因为转换/减少冲突的默认解决方案是移位)。这使得不可能使用FunType ::= Type产品,这会触发未使用的规则警告。

唯一简单的解决方案是完全放弃FunType,而代价是复制:

代码语言:javascript
复制
DFunAllT.        FunDef ::= Type Id "(" [ Arg ] ")" FunBody;
DFunAllV.        FunDef ::= "void" Id "(" [ Arg ] ")" FunBody;

如果重复工作困扰您,您可以留下以下因素:

代码语言:javascript
复制
DFunTI.   FunTypeId ::= Type Id;
DFunVI.   FunTypeId ::= "void" Id;
DFunAll.  FunDef ::= FunTypeId "(" [ Arg ] ")" FunBody;

不过,第一个可能更适合您的AST。

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

https://stackoverflow.com/questions/55630385

复制
相关文章

相似问题

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