I am writing a parser and it is required that a variable declaration consists of an identifier and an optional value initialization. If the starting word is var, the value initialization is obligatory. It starting with an assignment sign (<-) and an expression. The type of expression is assigned to variable at the compile time. \
TRUE : 'true';
FALSE: 'false';
//types
NUMBER: 'number';
BOOL: 'bool';
STRING: 'string';
RETURN: 'return';
VAR: 'var';
DYNAMIC: 'dynamic';
FUNC: 'func';
FOR: 'for';
UNTIL: 'until';
BY: 'by';
BREAK: 'break';
CONTINUE: 'continue';
IF: 'if';
ELSE: 'else';
ELIF: 'elif';
BEGIN: 'begin';
END: 'end';
/* LOGIC OPERATORS */
NOT: 'not';
AND: 'and';
OR: 'or';
/* ARITHMETIC OPERATORS */
// NEV: '-'; //overlap with SUB
ADD: '+';
SUB: '-';
MUL: '*';
DIV: '/';
MOD: '%';
/* STRING OPERATORS */
CONCAT : '...';
/* RELATIONAL OPERATORS */
EQ: '=';
NOT_EQ: '!=';
LT: '<';
GT: '>';
LTE: '<=';
GTE: '>=';
STRINGCMP: '=='; // Compare two same strings, STRING operand's type
ASSIGN : '<-';
/* SEPERATORS */
R_OPEN: '('; //ROUND
R_CLOSE: ')';
SQ_OPEN: '['; //SQUARE
SQ_CLOSE: ']';
C_OPEN: '{'; //CURLY
C_CLOSE: '}';
COMMA: ',';
SEMI: ';';
/* LITERAL */
// Fragment
fragment DIGIT : [0-9];
fragment DECIMALPART : DIGIT* ('.' DIGIT | DIGIT '.') DIGIT*;
fragment INTEGER : DIGIT DIGIT*;
fragment EXPONENTPART : [eE] ([-+])? INTEGER;
NUMBER_LITERAL : INTEGER EXPONENTPART? | DECIMALPART EXPONENTPART? ;
/* IDENTIFIER */
ID: [A-Za-z_][A-Za-z0-9_]*;
// INT: [0-9]+;
literal: NUMBER_LITERAL | TRUE | FALSE ;
program: NEWLINE* declare+ EOF;
declare: (var_decl | func_decl) NEWLINE+;
// All declarations and statements in this programming language
// must end with a newline character.
// Types
prim_type: NUMBER | BOOL | STRING;
//variable declaration
var_decl: (varDecl | arrayDecl ) ;
func_decl: 'func declaration';
arrayDecl: 'array declaration';
varDecl: (DYNAMIC | prim_type) ID (ASSIGN (literal | ID))?
| VAR ID ASSIGN (literal | ID)
;
// newline character
NEWLINE: '\n' | '\r\n';
/* COMMENT */
LINECMT : '##' ~[\n\r\f]* -> skip;
WS : [ \t\f\b]+ -> skip ; // skip spaces, tabs, newlines
ERROR_CHAR: . {raise ErrorToken(self.text)};
The issue lies in the failed test case that I received.
def test_204(self):
input = '''
var UyYv ## tv2xjibo,@
number u7i[6.385,406.606,76.243E39] <- 84.870E+57
'''
expect = '''Error on line 2 col 23:
'''
self.assertTrue(TestParser.test(input, expect, 204))
whereas my solution is (include the empty line created by NEWLINE):
Error on line 2 col 22:
My solution got 2 newlines while it is expected to detect 1 new newline. And I don't know why? I have been stuck on this for quite some time. Any ideas on how to resolve this?