Here is what I have tried:
parse : statement (NL statement)* EOF ;
statement : assignment '.' #assignmentStatement
| empty_line #emptyLineStatement
;
// bunch of stuff omitted for brevity
empty_line : WS* NL+ ; // want to ignore empty lines
WS : (' '|'\r'|'\t')+ -> skip ; // ignore whitespace
NL : '\n'; // new line is significant
Here is my test input:
PI -> 3.14159265359.
sqr(x) x * x.
z -> sqr(x:3).
circumference(r) PI * sqr(x:r).
fib(x) fib(x:x-1) + fib(x:x-2).
fib(x:2) 1.
fib(x:1) 1.
fib(x:0) 0.
I get the following error from the parser:
line 2:0 no viable alternative at input '\n'
line 5:0 no viable alternative at input '\n'
line 7:0 no viable alternative at input '\n'
and the following output from my Visitor
:
PI = 3.14159265359;;
ASSIGN sqr WITH x FROM [] RETURNING x TIMES x;
ASSIGN z AS CALL sqr WITH x = 3;
ASSIGN circumference WITH r FROM [] RETURNING PI TIMES CALL sqr WITH x = r;
ASSIGN fib WITH x FROM [] RETURNING CALL fib WITH x = x MINUS 1 PLUS CALL fib WITH x = x MINUS 2;
IF fib MATCHES x = 2 RETURN 1;
IF fib MATCHES x = 1 RETURN 1;
IF fib MATCHES x = 0 RETURN 0
If I remove the empty lines it does not produce the parser error and everything parses as expected:
PI -> 3.14159265359.
sqr(x) x * x.
z -> sqr(x:3).
circumference(r) PI * sqr(x:r).
fib(x) fib(x:x-1) + fib(x:x-2).
fib(x:2) 1.
fib(x:1) 1.
fib(x:0) 0.
with the expected output of:
PI = 3.14159265359;;
ASSIGN sqr WITH x FROM [] RETURNING x TIMES x;
ASSIGN z AS CALL sqr WITH x = 3;
ASSIGN circumference WITH r FROM [] RETURNING PI TIMES CALL sqr WITH x = r;
ASSIGN fib WITH x FROM [] RETURNING CALL fib WITH x = x MINUS 1 PLUS CALL fib WITH x = x MINUS 2;
IF fib MATCHES x = 2 RETURN 1;
IF fib MATCHES x = 1 RETURN 1;
IF fib MATCHES x = 0 RETURN 0
I have tried various variations of the empty_line
rule but it never changes so I am missing something very fundamental.
Solution:
I changed:
to:
and the errors went away!
Note:
This does not address the ability to match an empty line as significant.