Skip to content

Commit

Permalink
nitcc: detect and handle correctly states without shifts nor reduces #…
Browse files Browse the repository at this point in the history
…2846

This allows to detect and prevent crashes on some trivial mistakes.

More complex situation of empty languages are not yet detected.
  • Loading branch information
privat authored Jul 25, 2024
2 parents 14af05b + b8ab7e6 commit 8fae9fc
Show file tree
Hide file tree
Showing 13 changed files with 51 additions and 8 deletions.
4 changes: 2 additions & 2 deletions contrib/nitcc/src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ nitcc: nitcc1 nitcc.nit nitcc.sablecc

check: examples tests
tests:
cd ../tests && ./run
$(MAKE) -C ../tests
examples:
$(MAKE) -C ../example
$(MAKE) -C ../examples

clean:
rm -r \
Expand Down
17 changes: 12 additions & 5 deletions contrib/nitcc/src/lrautomaton.nit
Original file line number Diff line number Diff line change
Expand Up @@ -440,11 +440,9 @@ redef class Generator
add "\tredef fun action(parser) do"
if s.need_guard then
add "\t\tparser.peek_token.action_s{s.number}(parser)"
else if s.reduces.length == 1 then
else
add "\t\treduce_{s.reduces.first.cname}(parser)"
#gen_reduce_to_nit(s.reduces.first)
else
abort
end
add "\tend"

Expand Down Expand Up @@ -613,8 +611,11 @@ class LRState
# Shifts guarded by tokens
var guarded_shift = new HashMap[Token, Set[Item]]

# Does the state need a guard to perform an action?
fun need_guard: Bool do return not shifts.is_empty or reduces.length > 1
# Does the state need a guard that look at (or consume) the next token to perform an action?
# The only `false` case is a state with a single reduce action, it can be performed without checking the token.
# A shift always consume the token.
# Empty state with no valid future, must consume the token to produces a syntax error
fun need_guard: Bool do return not (shifts.is_empty and reduces.length == 1)

# Is the state LR0?
fun is_lr0: Bool do return reduces.length <= 1 and shifts.is_empty or reduces.is_empty
Expand Down Expand Up @@ -650,6 +651,12 @@ class LRState
abort
end
end
if shifts.is_empty and reduces.is_empty then
print "---"
print "Empty state {self} without any reduce or shift"
print "The possible past: {prefix} has no valid future"
end

# Token to remove as reduction guard to solve S/R conflicts
var removed_reduces = new Array[Token]
for t, a in guarded_reduce do
Expand Down
1 change: 1 addition & 0 deletions contrib/nitcc/tests/calc1.input
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1 + 2 - 3 - 4
1 change: 1 addition & 0 deletions contrib/nitcc/tests/calc1.sablecc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Ignored #10, #32;
e
= e '+' a
| e '-' a
| a
;
a =
| '(' e ')'
Expand Down
1 change: 1 addition & 0 deletions contrib/nitcc/tests/gram_empty.input
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
x
3 changes: 3 additions & 0 deletions contrib/nitcc/tests/gram_empty.sablecc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Parser
Ignored #10, #32;
s = s 'x' ;
1 change: 1 addition & 0 deletions contrib/nitcc/tests/gram_empty2.input
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
y x z
4 changes: 4 additions & 0 deletions contrib/nitcc/tests/gram_empty2.sablecc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Parser
Ignored #10, #32;
s = a ;
a = 'x' s | 'y' s 'z';
17 changes: 17 additions & 0 deletions contrib/nitcc/tests/sav/calc1.input.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
Start
e_1
e_1
e_0
e_2
a_2
n@(1:1-1:2)='1'
'+'@(1:3-1:4)
a_2
n@(1:5-1:6)='2'
'-'@(1:7-1:8)
a_2
n@(1:9-1:10)='3'
'-'@(1:11-1:12)
a_2
n@(1:13-1:14)='4'
Eof@(2:1-2:1)=''
1 change: 0 additions & 1 deletion contrib/nitcc/tests/sav/calc1.res
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
Runtime error: Aborted (./lrautomaton.nit:507)
3 changes: 3 additions & 0 deletions contrib/nitcc/tests/sav/gram_empty.input.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
NParserError@(1:1-1:2)='x'
Nodes[Node]
'x'@(1:1-1:2)
1 change: 1 addition & 0 deletions contrib/nitcc/tests/sav/gram_empty.res
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Empty state 0 without any reduce or shift
5 changes: 5 additions & 0 deletions contrib/nitcc/tests/sav/gram_empty2.input.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
NParserError@(1:5-1:6)='z'
Nodes[Node]
'y'@(1:1-1:2)
'x'@(1:3-1:4)
'z'@(1:5-1:6)

0 comments on commit 8fae9fc

Please sign in to comment.