0

My ANTLR Grammar for simple expressions is as below: This grammar works for most of the scenarios except when I try to use negative numbers.

abs(1.324) is valid

abs(-1.324) is being thrown as an error. 

Or if the expression is just a negative number such as -1.344 I am having the following error in the console.

enter image description here

grammar ExpressionGrammar;

parse: expr EOF;

expr:
    MIN expr
    | expr ( MUL | DIV) expr
    | expr ( ADD | MIN) expr
    | expr  ( MOD )  expr
    | NUM
    | ID
    | STRING
    | function
    | '(' expr ')';

function: ID '(' arguments? ')';

arguments: expr ( ',' expr)*;

/* Tokens */

MUL: '*';
DIV: '/';
MIN: '-';
ADD: '+';
MOD: '%';
OPEN_PAR: '(';
CLOSE_PAR: ')';

NUM: ([0-9]*[.])?[0-9]+;
STRING: '"' ~ ["]* '"';
fragment ID_NODE: [a-zA-Z_$][a-zA-Z0-9_$]*;
ID: ID_NODE ('.' ID_NODE)*;
COMMENT: '/*' .*? '*/' -> skip;
LINE_COMMENT
    : '//' ~[\r\n]* -> skip
    ;
WS: [ \r\t\n]+ -> skip;
Veryon890
  • 330
  • 1
  • 4
  • 15
  • Perhaps because `function` is a reserved word in the language of your runtime? – Bart Kiers Aug 25 '21 at 04:48
  • @BartKiers I don't think so, I quickly changed ```function``` to ```func``` and generated my files to check. It still is giving me the same error. It does not happen with functions alone. If I just try to return a negative number say ```-1.23424``` it's throwing me the error. – Veryon890 Aug 25 '21 at 05:00
  • The grammar is definitely not the issue (see my answer). And when (re) generating the lexer- and parser classes, you're not getting a warning? Just to be sure: this is your entire grammar? You've not trimmed it down in any way for SO? Could you include the code that is responsible for producing that error? – Bart Kiers Aug 25 '21 at 05:59
  • The index error probably stems from code that accesses the generated parse tree, in the application. We need to see the target (C# probably) code and how you traverse your parse tree. – Mike Lischke Aug 25 '21 at 06:29
  • The grammar works fine in either Antlr4cs (the ancient tool and runtime that keeps going and going) or Antlr4 "official". But, this is NOT with the C# runtime! The error prints "ParserRuleContext.ts", which is Typescript, but there are tags for "antlr3", "antlrworks", and "antlr4cs". These tags are really misleading because it has zero to do with any of those targets and/or tools. – kaby76 Aug 25 '21 at 11:57
  • 1
    Just a guess, but could it be that your negative number is not actually treated as a negative number by the grammar, but rather a minus character (a MIN token) directly followed by a number (NUM token)? – Boise Aug 25 '21 at 15:36
  • 1
    OP: are you getting this error on some evaluation of the parse tree, i.e., a tree walk? Given Bart's analysis, the error likely stems from conflating the number of children in `expr:1` (1 or 2) and accessing the actual children of `expr:5` (always 1). Certainly would explain the exact error message only occurring on negative numbers. – GRosenberg Aug 26 '21 at 01:47
  • sorry for the delay in response. Mike, Boise, and Rosenberg you are right, the issue is with how I walk and access the generated tree. According to my logic negative number is being treated as a MIN Token and I check for the left and right operand of this minus. This error in specific occurs when the logic checks for left operand ( i.e. current index - 1 ) and the index comes out to be "-1" and hence the error. How are these situations usually dealt with ? How can we make sure that the MIN ( minus ) being used is for a number and not an actual operator ? – Veryon890 Aug 31 '21 at 05:58
  • `How can we make sure that the MIN ( minus ) being used is for a number and not an actual operator?` The short answer is that this is a semantic, not syntactic issue. Therefore, analysis of the larger context that contains the expression is required to answer definitively: `abs(-1.324)` vs `abs(2-1.324)` vs `abs(2--1.324)` – GRosenberg Sep 04 '21 at 17:56

1 Answers1

2

The grammar seems fine to me. It could be a bug with the runtime you're using, but that seems odd to me, given you're not doing anything special.

With the Java runtime, this is what I get when parsing/lexing the input abs(-1.324):

The following tokens are produced:

ID                                  `abs`
OPEN_PAR                            `(`
MIN                                 `-`
NUM                                 `1.324`
CLOSE_PAR                           `)`
EOF                                 `<EOF>`

and the entry point parse gives:

enter image description here

Bart Kiers
  • 166,582
  • 36
  • 299
  • 288