问题描述
我正在尝试使用 flex 和 bison 创建一个简单的编译器,但是我写下的所有规则都证明是无用的“14 个无用的非终结符和 66 个无用的规则”。什么使规则无用,有没有办法修复它?
File: Decl_Class'*' 'EOF'
Decl_Class: CLASS IDENT '(' EXTENDS IDENT ')' '?' {Field'*'}
Field: Variable
|Constructor
|Method
Variable: Modifier'*' Expr_type Decl_variables
Decl_variables: Decl_variable
|Decl_variable ',' Decl_variables
Decl_variable: IDENT
|IDENT '=' Expr
Constructor: Modifier'*' IDENT '(' Expr_type | VOID ')' IDENT '(' Params '?' ')' {Instructions'*'}
Method: Modifier'*' '(' Expr_type | VOID ')' IDENT '(' Params '?' ')' {Instructions'*'}
Modifier: IDENT
Expr: IDENT
Params: '(' Expr_type ')' IDENT | '(' Expr_type ')' IDENT ',' Params
Expr_type: BOOLEAN | INT | DOUBLE | IDENT | INTEGER | REAL | TRU | FALS
| THIS | NULLVAL
| '(' Expr ')'
| Access|Access '=' Expr|Access '(' L_Expr '?' ')'
| NEW IDENT '(' L_Expr '?' ')'
| '+''+'Expr | '-''-'Expr | Expr'+''+' | Expr'-''-'
| '!'Expr | '-'Expr | '+'Expr
| Expr Operator Expr
| '(' Expr_type ')' Expr_type
Operator: "==" | "!=" | "<" | "<=" | ">" | ">=" | "+" | "-" | "*" | "/" | "%" | "&&" | "||"
Access: IDENT | Expr '.' IDENT
L_Expr: Expr | Expr ',' L_Expr
Instruction: ';'
| Expr';'
| Expr_type Decl_variables';'
| IF '(' Expr ')' Instruction
| IF '(' Expr ')' Instruction ELSE Instruction
| WHILE '(' Expr ')' Instruction
| FOR '(' L_Expr '?' ';' Expr '?' ';' L_Expr '?'')' Instruction
| FOR '(' Expr ')' Decl_variables ';' Expr '?' ';' L_Expr '?'')' Instruction { Instructions'*' }
| RETURN Expr '?'';'
解决方法
Decl_Class: CLASS IDENT '(' EXTENDS IDENT ')' '?' {Field'*'}
这里 {}
里面的部分是一个代码动作(编译时会产生语法错误),而不是对 Field
非终结符的引用。所以 Field
从来没有被实际使用过,它引用的非终端也没有。这就是使它们无用的原因:它们从未被使用过。
PS:在语法的不同地方,您使用 '*'
和 '?'
的方式表明其意图可能是分别匹配零个或多个或零或一个项目。请注意,所有 '*'
和 '?'
所做的都是将标记与给定值匹配。在 bison 中没有重复某些内容或使其成为可选的语法快捷方式 - 您需要为此定义单独的非终结符。
PPS:在大多数(所有?)具有 ++
和 --
运算符的语言中,它们由单个标记组成,而不是两个后续的 '+'
或 '-'
标记(所以- -x
将是双重否定,只有 --x
之间没有空格的 -
将是减量)。因此,您对自减和自增运算符的规则在这方面是不寻常的。