1
votes

I am currently trying to implement a simple language in ANTLR. The problem is I don't know how to get around my circular logic, or how to factor it out. When I test it out, everything is declared as sexp, it does not drill down to the final type. Any help would be appreciated. Is there a way to factor sexp for each type of operator?

I also get the error: line 2:0 no viable alternative at input ''

when trying to parse the following code

(+ 2 3)

An example of the language is like this:

to add 2 to 3 --> (+ 2 3)

to add 2 to (2 multiplied by 3) --> (+ 2 (* 2 3 ) )

Its basically an operator followed by two expressions, which are the operands.

This is what I have so for:

lexer:

lexer grammar LizpLexer;
WS: [ \t\r\n] -> skip;

TRUE: 'true';
FALSE: 'false';
AND: 'and';
OR: 'or';
NOT: 'not';
LPARENT: '(';
RPARENT: ')';
ADD: '+';
SUBTRACT: '-';
ABSOLUTE: 'abs';
CEILING: 'ceil';
FLOOR: 'floor';
ROUND: 'round';
MULTIPLY: '*';
DIVIDE: '/';
MAX: 'max';
MIN: 'min';
EQUALS: '=';
NEQUALS  : '/=';  
GTEQUALS : '>=';  
LTEQUALS : '<=';  
GT       : '>';  
LT       : '<'; 
PRINT: 'print';
CONDITIONAL: 'cond';
IF: 'if';
SET: 'set';


NUMBER: DIGIT+ ('.' DIGIT*)?;
fragment CHAR: [_a-zA-Z];
fragment DIGIT: [0-9];

ID: CHAR (CHAR | DIGIT)*;

and the parser

parser grammar LizpParser;

options {tokenVocab=LizpLexer;}

program : sexp+ EOF;

sexp 
    : atom 
    | arithexpr 
    | relexpr 
    | boolexpr 
    | conexpr 
    | printexpr 
    | bindexpr
    ;

atom
    : ID | NUMBER;

arithexpr
    : unaryexpr 
    | binaryexpr 
    | naryexpr
    ;

unaryexpr 
    : LPARENT unaryOp sexp RPARENT
    ;

unaryOp 
    : SUBTRACT 
    | ABSOLUTE 
    | CEILING
    | FLOOR
    | ROUND
    ;

binaryexpr 
    : LPARENT binaryOp sexp sexp RPARENT
    ;

binaryOp 
    : DIVIDE
    ;

naryexpr 
    : LPARENT naryOp sexp sexp+ RPARENT
    ;

naryOp 
    : ADD 
    | MULTIPLY 
    | MAX 
    | MIN
    ;

relexpr 
    : LPARENT relOp sexp sexp RPARENT
    ;

relOp 
    : EQUALS
    | NEQUALS 
    | LT 
    | GT 
    | LTEQUALS 
    | GTEQUALS
    ;


boolexpr 
    : notexpr 
    | andexpr 
    | orexpr
    ;

notexpr 
    : LPARENT NOT sexp RPARENT
    ;

andexpr 
    : LPARENT AND sexp+ RPARENT
    ;

orexpr 
    : LPARENT OR sexp+ RPARENT
    ;

conexpr 
    : ifexpr 
    | condexpr
    ;

ifexpr 
    : LPARENT IF sexp sexp sexp? RPARENT
    ;

condexpr 
    : LPARENT CONDITIONAL sexp+ RPARENT
    ;

printexpr 
    : LPARENT PRINT sexp+ RPARENT
    ;

bindexpr 
    : LPARENT SET ID sexp RPARENT
    ;
1

1 Answers

1
votes

You grammar worked for me. Note I was using the ANTLR v4.2 Java target. This is the parse tree I generated from (+ 2 3) using TestRig:

enter image description here

If you're using C# target, try again with the Java target to see if the same issue is encountered. I have the impression that the C# target still contains bugs.