How to have `\n` significant except when it is on a line by itself?

75 views Asked by At

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.

How can I get this to parse an empty line that has only a \n or all whitespace and a \n?

1

There are 1 answers

0
AudioBubble On

Solution:

I changed:

NL : '\n' ;

to:

NL : '\n'+ ;

and the errors went away!

Note:

This does not address the ability to match an empty line as significant.