Reputation: 111
In my grammar with antlrworks, I can get noviablealtexception for rules like if, while which need corresponding right and left brackets. However, in java, i cannot get noviablealtexception.
loop_statement: (WHILE LPAREN expr RPAREN statement)
| (DO statement WHILE LPAREN expr RPAREN);
condition_statement
: IF LPAREN expr RPAREN statement (options {greedy=true;}: ELSE statement)?
In statement rule I have a block rule which is,
statement_blocks
: (LBRACE statement* RBRACE)
;
And statement rule is below,
statement
: var_dec
| statement_blocks
| condition_statement
| loop_statement
| expr_statement
;
Before posting this I've checked some examples. I think i need to add EOF at the end of each rule. When I add EOF for those rules, I get different errors. For example,
loop_statement: ((WHILE LPAREN expr RPAREN statement)
| (DO statement WHILE LPAREN expr RPAREN)) EOF;
condition_statement
: (
(IF LPAREN expr RPAREN statement (options {greedy=true;}: ELSE statement)?
)EOF
These are what I get for the following inputs;
if(s==d){
d=s;
if(a=n){
s=h;
}
a=g;
}
line 6:0 missing EOF at 'a'
When I remove the first left bracket from the first "if"
if(s==d)
d=s;
if(a=n){
s=h;
}
a=g;
}
testcases/new file line 3:0 missing EOF at 'if',
testcases/new file line 6:0 missing EOF at 'a'
while(s==d){
d=s;
while(a=n){
s=h;
}
a=g;
}
line 6:0 missing EOF at 'a'
When I remove the first left bracket from the first "while"
while(s==d)
d=s;
while(a=n){
s=h;
}
a=g;
}
testcases/new file line 3:0 missing EOF at 'while'
testcases/new file line 6:0 missing EOF at 'a'
Upvotes: 4
Views: 5737
Reputation: 170148
No, you need to place EOF
at the end of your "main" parser rule, not after more than one statement. By doing so, the parser expects the end of the file after such statements (which is not correct, of course).
My guess is that your entry point does not contain EOF
causing the parser to stop prematurely instead of throwing an error/exception when it stumbles upon invalid input.
Here's a demo (note the EOF
after the parse
rule):
grammar T;
parse
: statement+ EOF
;
statement
: var_dec
| statement_blocks
| c=condition_statement {System.out.println("parsed :: " + $c.text);}
;
var_dec
: ID '=' ID ';'
;
statement_blocks
: LBRACE statement* RBRACE
;
condition_statement
: IF LPAREN expr RPAREN statement (options {greedy=true;}: ELSE statement)?
;
expr
: ID '==' ID
;
IF : 'if';
ELSE : 'else';
ID : 'a'..'z'+;
LBRACE : '{';
RBRACE : '}';
LPAREN : '(';
RPAREN : ')';
SPACE : (' ' | '\t' | '\r' | '\n')+ {skip();};
which can be tested with the class:
import org.antlr.runtime.*;
public class Main {
public static void main(String[] args) throws Exception {
TLexer lexer = new TLexer(new ANTLRFileStream("in.txt"));
TParser parser = new TParser(new CommonTokenStream(lexer));
parser.parse();
}
}
If you now parse the input file (in.txt
):
if(s==d) {
d=s;
if(a==n){
s=h;
}
a=g;
}
there's no problem, as you can see:
java -cp antlr-3.3.jar org.antlr.Tool T.g
javac -cp antlr-3.3.jar *.java
java -cp .:antlr-3.3.jar Main
parsed :: if(a==n){s=h;}
parsed :: if(s==d){d=s;if(a==n){s=h;}a=g;}
And if you remove a (
or )
from the file in.txt
, you will get the following (similar) error:
in.txt line 1:8 missing RPAREN at '{'
Upvotes: 2