2
votes

I have the following grammar and I want to match the String "{name1, name2}". I just want lists of names/intergers with at least one element. However I get the error:
line 1:6 no viable alternative at character ' '
line 1:11 no viable alternative at character '}'
line 1:7 mismatched input 'name' expecting SIMPLE_VAR_TYPE

I would expect whitespaces and such are ignored... Also interesting is the error does not occur with input "{name1,name2}" (no space after ','). Heres my gramar

grammar NusmvInput;
options {
  language = Java;
}
@header {
  package secltlmc.grammar;
}
@lexer::header {
  package secltlmc.grammar;
}
specification : 
     SIMPLE_VAR_TYPE EOF
     ;     
INTEGER 
    : ('0'..'9')+
    ;
SIMPLE_VAR_TYPE 
    : ('{' (NAME | INTEGER) (',' (NAME | INTEGER))* '}'  )
    ;
NAME 
    : ('A'..'Z' | 'a'..'z') ('a'..'z' | 'A'..'Z' | '0'..'9' | '_' | '$' | '#' | '-')*
    ;
WS 
    : (' ' | '\t' | '\n' | '\r')+ {$channel = HIDDEN;} 
    ;

And this is my testing code

package secltlmc;
public class Main {
    public static void main(String[] args) throws 
            IOException, RecognitionException {
        CharStream stream = new ANTLRStringStream("{name1, name2}");
        NusmvInputLexer lexer = new NusmvInputLexer(stream);
        CommonTokenStream tokenStream = new CommonTokenStream(lexer);
        NusmvInputParser parser = new NusmvInputParser(tokenStream);
        parser.specification();
    }
}

Thanks for your help.

2

2 Answers

2
votes

The problem is that you are trying to parse SIMPLE_VAR_TYPE with the lexer, i.e. you are trying to make it a single token. In reality, it looks like you want a multi-token production, since you'd like whitespace to be re-directed to hidden channel through WS.

You should change SIMPLE_VAR_TYPE from a lexer rule to a parser rule by changing its initial letter (or better yet, the entire name) to lower case.

specification : 
     simple_var_type EOF
     ;    

simple_var_type 
    : ('{' (NAME | INTEGER) (',' (NAME | INTEGER))* '}'  )
    ;
1
votes

The defintion of SIMPLE_VAR_TYPE specifies the following expression:

  • Open {
  • followed by one of NAME or INTEGER
  • follwoed by zero or more of:
    • comma (,) followed by one of NAME or INTEGER
  • followed by closing }

Nowhere does it allow white-space in the input (neither NAME nor INTEGER allows it either), so you get an error when you supply one

Try:

SIMPLE_VAR_TYPE 
: ('{' (NAME | INTEGER) (WS* ',' WS* (NAME | INTEGER))* '}'  )
;