[antlr-interest] Re: Runtime rule multiplicity
Matthew Mastracci
matthew at mastracci.com
Fri May 12 19:15:53 PDT 2006
I found something that works, but I think I might be running into a
minor bug in the state machine code. This is the grammar I'm using - it
works for the two test cases I fed it, but the first case throws a
spurious NoViableAltException:
ID NUMBER NUMBER NUMBER ID NUMBER NUMBER NUMBER
and
ID NUMBER NUMBER ID NUMBER NUMBER NUMBER
parser grammar Test;
options {
output=AST;
ASTLabelType=CommonTree;
}
tokens { ID; NUMBER; }
@members {
Stack<Integer> current = new Stack<Integer>();
Stack<Integer> max = new Stack<Integer>();
private int resolveArgumentCount(String name) {
return 3;
}
}
start
: statement+;
statement
: ID { current.push(0);
max.push(resolveArgumentCount($ID.text)); System.out.println("statement"); }
parameter
{ System.out.println("statement done"); };
parameter
: { System.out.println("parameter " + (current.peek() + 1) + "
of " + max.peek()); }
parameter_contents
( {current.peek() + 1 < max.peek()}? =>
{ current.push(current.pop() + 1); } parameter )?;
parameter_contents
: NUMBER { System.out.println("number"); } | statement {
System.out.println("statement"); } ;
The only problem is that the parameter state machine seems to be
throwing a NoViableAltException in the case where the syntactic
predicate fails, rather than returning gracefully like I would have
expected. I might be misunderstanding the generated parser a bit, but
it seems like it throwing an exception where it could just be doing
nothing via the empty alt2 case label.
The first two states make sense, but I think that
if ( LA2_0==NUMBER && current.peek() + 1 < max.peek()) {
int LA2_1 = input.LA(2);
if ( current.peek() + 1 < max.peek() ) {
alt2=1;
}
else if ( current.peek() + 1 < max.peek() ) {
alt2=2;
}
else {
NoViableAltException nvae =
new NoViableAltException("36:9: ({...}? =>
parameter )?", 2, 1, input);
throw nvae;
}
}
else if ( LA2_0==ID && current.peek() + 1 < max.peek()) {
int LA2_2 = input.LA(2);
if ( current.peek() + 1 < max.peek() ) {
alt2=1;
}
else if ( true ) {
alt2=2;
}
else {
NoViableAltException nvae =
new NoViableAltException("36:9: ({...}? =>
parameter )?", 2, 2, input);
throw nvae;
}
}
else if ( LA2_0==-1 ) {
alt2=2;
}
else {
NoViableAltException nvae =
new NoViableAltException("36:9: ({...}? =>
parameter )?", 2, 0, input);
throw nvae;
}
Shouldn't this state machine end in alt2=2 for all cases instead?
if ( LA2_0==NUMBER && current.peek() + 1 < max.peek()) {
int LA2_1 = input.LA(2);
if ( current.peek() + 1 < max.peek() ) {
alt2=1;
}
else if ( current.peek() + 1 < max.peek() ) {
alt2=2;
}
else {
NoViableAltException nvae =
new NoViableAltException("36:9: ({...}? =>
parameter )?", 2, 1, input);
throw nvae;
}
}
else if ( LA2_0==ID && current.peek() + 1 < max.peek()) {
int LA2_2 = input.LA(2);
if ( current.peek() + 1 < max.peek() ) {
alt2=1;
}
else if ( true ) {
alt2=2;
}
else {
NoViableAltException nvae =
new NoViableAltException("36:9: ({...}? =>
parameter )?", 2, 2, input);
throw nvae;
}
}
else {
alt2=2;
}
More information about the antlr-interest
mailing list