JISON表达式类型转换语法歧义问题求解
问题描述
使用JISON开发小型翻译器时,在实现类型转换功能时遇到语法歧义:
需要添加的类型转换产生式为:
expr: OPEN_PAREN type CLOSE_PAREN expr
但现有语法中已存在括号表达式产生式:
expr: '(' expr ')'
两者冲突导致歧义。当前表达式语法定义如下:
expr : expr PLUS expr | expr MINUS expr | expr TIMES expr | expr DIV expr | expr MOD expr | expr POWER expr | MINUS expr %prec UMINUS | expr LESS_THAN expr | expr GREATER_THAN expr | expr LESS_OR_EQUAL expr | expr GREATER_OR_EQUAL expr | expr EQUALS expr | expr DIFFERENT expr | expr OR expr | expr AND expr | NOT expr | OPEN_PAREN expr CLOSE_PAREN | INT_LITERAL | DOUBLE_LITERAL | BOOLEAN_LITERAL | CHAR_LITERAL | STRING_LITERAL | ID;
此前用于处理歧义的优先级与结合性规则:
%left 'ASSIGNEMENT' %left 'OR' %left 'AND' %left 'XOR' %left 'EQUALS', 'DIFFERENT' %left 'LESS_THAN', 'GREATER_THAN', 'LESS_OR_EQUAL', 'GREATER_OR_EQUAL' %left 'PLUS', 'MINUS' %left 'TIMES', 'DIV', 'MOD' %right 'POWER' %right 'UMINUS', 'NOT'
尝试合并产生式后仍存在歧义:
expr: OPEN_PAREN type CLOSE_PAREN expr | OPEN_PAREN expr CLOSE_PAREN
询问是否无需重写无歧义语法,仅通过JISON解决该歧义,并求解决方案思路。
解决方案思路
无需重写完整的无歧义语法,通过JISON的优先级机制或语法结构微调即可解决,具体思路如下:
1. 给类型转换产生式指定更高优先级
类型转换的语义绑定应该比普通括号表达式更紧密,因此可以为其设置一个高于现有所有优先级的标记:
- 首先在优先级声明部分添加一个最高级的优先级标记,比如
TYPECAST:%right 'TYPECAST' %right 'UMINUS', 'NOT' %right 'POWER' %left 'TIMES', 'DIV', 'MOD' %left 'PLUS', 'MINUS' %left 'LESS_THAN', 'GREATER_THAN', 'LESS_OR_EQUAL', 'GREATER_OR_EQUAL' %left 'EQUALS', 'DIFFERENT' %left 'XOR' %left 'AND' %left 'OR' %left 'ASSIGNEMENT' - 然后修改类型转换的产生式,通过
%prec指定其使用TYPECAST优先级:expr: OPEN_PAREN type CLOSE_PAREN expr %prec 'TYPECAST' | OPEN_PAREN expr CLOSE_PAREN // ... 其他expr规则
这样JISON会优先匹配类型转换规则,而非普通括号表达式,从而消除歧义。
2. 拆分非终结符,明确语法层级
将原有的expr拆分为两个非终结符,区分基础表达式和复杂表达式:
- 定义
primary_expr用于表示无法再拆分的基础表达式,包括普通括号表达式、字面量和标识符:primary_expr: OPEN_PAREN expr CLOSE_PAREN | INT_LITERAL | DOUBLE_LITERAL | BOOLEAN_LITERAL | CHAR_LITERAL | STRING_LITERAL | ID; - 然后将
expr的规则调整为包含类型转换、二元/一元操作,并以primary_expr作为基础:expr: OPEN_PAREN type CLOSE_PAREN expr | expr PLUS expr | expr MINUS expr | expr TIMES expr | expr DIV expr | expr MOD expr | expr POWER expr | MINUS expr %prec UMINUS | expr LESS_THAN expr | expr GREATER_THAN expr | expr LESS_OR_EQUAL expr | expr GREATER_OR_EQUAL expr | expr EQUALS expr | expr DIFFERENT expr | expr OR expr | expr AND expr | NOT expr | primary_expr;
这种结构下,语法会明确区分:(type) expr属于expr的类型转换规则,而(expr)属于primary_expr的普通括号规则,从语法结构上消除歧义。
3. 确保type的词法/语法无歧义
如果type包含关键字(如int、double),需在词法分析器中把这些关键字识别为独立的TYPE_* token,避免被解析为ID;如果type允许自定义类型名(即ID),则结合上述优先级方案,确保括号内的ID优先被解析为type而非expr的一部分。
内容的提问来源于stack exchange,提问作者luisepa1420
相关产品推荐
相关产品推荐

