1
votes

I am trying to create a simple compiler using flex and bison, however all the rules i've written down have shown to be useless "14 useless nonterminals and 66 useless rules". What makes a rule useless and is there a way to fix it?

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 '?'';'
1

1 Answers

1
votes
Decl_Class: CLASS IDENT '(' EXTENDS IDENT ')' '?' {Field'*'}

Here the part inside the {} is a code action (which will produce a syntax error when compiled), not a reference to the Field non-terminal. So Field is never actually used and neither are the non-terminal referenced by it. That's what makes them useless: they're never used.

PS: At various places in your grammar you're using '*' and '?' in a way that suggests the intention may be to match zero or more or zero or one items respectively. Be aware that all '*' and '?' do is to match a token with the given value. There is no syntactic shortcut to repeat something or make it optional in bison - you'll need to define separate non-terminals for that.

PPS: In most (all?) languages that have ++ and -- operators, those consist of a single token not two subsequent '+' or '-' tokens (so - -x would be double negation and only --x without the space between the -s would be a decrement). So your rules for the decrement and increment operators are unusual in that regard.