语法问题 #82
-
然而如果不用Functype,而是枚举T_INT或T_VOID,就可以正常输出,请问是我原本的语法有误吗 |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 4 replies
-
可能是存在移入规约冲突,可以关注编译时的 warning |
Beta Was this translation helpful? Give feedback.
-
我也遇见了这个问题,全局变量里面,Decl或者FuncDef的开头如果用Btype会报段错误,用T_INT才不会。 |
Beta Was this translation helpful? Give feedback.
-
确实是文法发生了 reduce-reduce conflict ,FuncType 和 BType 都可以直接推出 T_INT ,而且 T_INT 后面都可以接 T_IDENTIFIER ,bison 只看一个 symbol 不知道是规约成函数定义 FuncDef 还是变量声明 VarDecl 。报段错误是因为 bison 自动忽略了 FuncType 和 BType 中最靠后的规则,导致 parser 原来可以识别的很多结构都无法识别。 // A wrong example
FuncDef:
FuncType T_IDENTIFIER T_L_PAREN T_R_PAREN Block {
$$ = AddTreeNode($5, "FunctionDecl", $2->name);
delete $2;
}
;
VarDecl:
BType VarDef T_SEMI {
$$ = AddTreeNode($2, "VarDecl");
}
;
VarDef:
T_IDENTIFIER {
delete $1;
}
| T_IDENTIFIER T_EQUAL InitVal {
$$ = $3;
delete $1;
}
;
FuncType: T_VOID | T_INT;
BType: T_INT | T_CHAR | T_LONG T_LONG; 编译时遇到 conflict 会报 warning 但信息很少,可以直接用 bison 加上 bison /workspace/SYsU-lang/parser/parser.y -Wcounterexamples 适当的枚举确实可以解决该冲突,我的方法是直接放弃使用 FuncType 。 FuncDef:
T_VOID T_IDENTIFIER T_L_PAREN T_R_PAREN Block {
$$ = AddTreeNode($5, "FunctionDecl", $2->name);
delete $2; // deletes node of the identifier to avoid being printed.
}
| BType T_IDENTIFIER T_L_PAREN T_R_PAREN Block {
$$ = AddTreeNode($5, "FunctionDecl", $2->name);
delete $2; // deletes node of the identifier to avoid being printed.
}
; |
Beta Was this translation helpful? Give feedback.
确实是文法发生了 reduce-reduce conflict ,FuncType 和 BType 都可以直接推出 T_INT ,而且 T_INT 后面都可以接 T_IDENTIFIER ,bison 只看一个 symbol 不知道是规约成函数定义 FuncDef 还是变量声明 VarDecl 。报段错误是因为 bison 自动忽略了 FuncType 和 BType 中最靠后的规则,导致 parser 原来可以识别的很多结构都无法识别。
编译时遇到 conflict 会报 warning 但信息很少,可以直接用 bison 加上
-Wcountere…