YACC语法问题:无法检测函数,多次修改无效
解决YACC无法检测函数的问题
看起来你遇到的核心问题是YACC语法规则没有正确识别函数声明/定义,或者语义动作没有正确标记函数。结合你给出的代码片段,我整理了几个关键的修复点:
1. 修正program规则的结构
你的当前program规则只能匹配单个顶层元素(函数声明、变量声明或函数定义),但实际程序应该支持多个顶层元素。改成递归结构才能正确解析整个程序:
program : program function-decl | program decl | program function-def | /* 空规则,匹配空程序 */ ;
这样YACC会逐个解析所有顶层的函数和变量声明,不会漏掉后续的函数。
2. 补全函数相关的语法规则
你只给出了program里的函数规则名,但没有具体实现。必须明确定义函数声明和定义的结构,才能让YACC识别它们:
// 函数声明:返回类型 + 函数名 + 参数列表 + 分号 function-decl : kind ID LPAREN param-list RPAREN SEMICOLON { // 这里添加函数检测的语义动作 tok_type = "function"; t.check_token(tok_type, $2, line_no, bodyCheck, parameter); // 可以额外记录函数的返回类型($1对应的类型) } ; // 函数定义:返回类型 + 函数名 + 参数列表 + 函数体 function-def : kind ID LPAREN param-list RPAREN LBRACE stmt-list RBRACE { tok_type = "function"; t.check_token(tok_type, $2, line_no, bodyCheck, parameter); // 处理函数体的逻辑 } ; // 参数列表:支持空参数或多个参数 param-list : /* 空参数列表 */ | param param-many ; param : kind ID ; // 单个参数:类型 + 参数名 param-many : /* 空 */ | param-many COMMA param // 多个参数用逗号分隔 ; // 假设你有语句列表的规则(函数体里的内容) stmt-list : /* 空 */ | stmt-list stmt ; stmt : /* 根据你的语言定义语句规则,比如赋值、条件判断等 */ ;
3. 确保规则匹配的优先级正确
YACC会按照规则的顺序尝试匹配,不过函数声明/定义的结构(kind ID ()和变量声明(kind ID ;)前缀相似但后续符号不同,YACC会通过移进后续的(来区分两者,不会出现归约冲突。但要确保kind规则只匹配KW_INT和KW_FLOAT,没有其他歧义。
4. 检查语义动作的完整性
你的变量声明已经在var-list里添加了check_token的调用,函数的检测必须在function-decl和function-def的语义动作里做同样的操作,并且把tok_type设为"function",这样你的检测逻辑才能识别到函数。
额外排查点
- 确认词法分析器(LEX/FLEX)正确识别了
LPAREN(左括号)、RPAREN(右括号)、LBRACE(左大括号)、RBRACE(右大括号)这些符号,没有把它们错误归类。 - 检查是否存在移进/归约冲突,可以用YACC的
-v选项生成输出文件,查看冲突信息,针对性调整规则。
内容的提问来源于stack exchange,提问作者A.Ell
相关产品推荐
相关产品推荐

