[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