1 ;;; test-lr-error-recovery-01.scm --
3 ;;Test error recovery with a terminator terminal.
6 (load "common-test.scm")
8 (define (doit . tokens)
9 (let ((parser (lalr-parser
13 (script (lines) : (reverse $1)
15 (lines (lines line) : (cons $2 $1)
17 (line (NEWLINE) : (list 'line $1)
18 (NUMBER NEWLINE) : (list 'line $1 $2)
19 (NUMBER NUMBER NEWLINE) : (list 'line $1 $2 $3)
21 ;;This semantic action will cause "(recover $1
22 ;;$2)" to be the result of the offending line.
23 (error NEWLINE) : (list 'recover $1 $2)))))
24 (parser (make-lexer tokens) error-handler)))
26 ;;; --------------------------------------------------------------------
27 ;;; No errors, grammar tests.
34 (doit (make-lexical-token 'NEWLINE #f #\newline))
35 => '((line #\newline)))
38 (doit (make-lexical-token 'NUMBER #f 1)
39 (make-lexical-token 'NEWLINE #f #\newline))
40 => '((line 1 #\newline)))
43 (doit (make-lexical-token 'NUMBER #f 1)
44 (make-lexical-token 'NUMBER #f 2)
45 (make-lexical-token 'NEWLINE #f #\newline))
46 => '((line 1 2 #\newline)))
49 (doit (make-lexical-token 'NUMBER #f 1)
50 (make-lexical-token 'NEWLINE #f #\newline)
51 (make-lexical-token 'NUMBER #f 2)
52 (make-lexical-token 'NEWLINE #f #\newline))
53 => '((line 1 #\newline)
57 (doit (make-lexical-token 'NUMBER #f 1)
58 (make-lexical-token 'NEWLINE #f #\newline)
59 (make-lexical-token 'NUMBER #f 2)
60 (make-lexical-token 'NEWLINE #f #\newline)
61 (make-lexical-token 'NUMBER #f 3)
62 (make-lexical-token 'NEWLINE #f #\newline))
63 => '((line 1 #\newline)
68 (doit (make-lexical-token 'NUMBER #f 1)
69 (make-lexical-token 'NEWLINE #f #\newline)
70 (make-lexical-token 'NUMBER #f 2)
71 (make-lexical-token 'NEWLINE #f #\newline)
72 (make-lexical-token 'NUMBER #f 3)
73 (make-lexical-token 'NEWLINE #f #\newline)
74 (make-lexical-token 'NUMBER #f 41)
75 (make-lexical-token 'NUMBER #f 42)
76 (make-lexical-token 'NEWLINE #f #\newline))
77 => '((line 1 #\newline)
80 (line 41 42 #\newline)))
82 ;;; --------------------------------------------------------------------
83 ;;; Successful error recovery.
86 ;;The BAD triggers an error, recovery happens, the first NEWLINE is
87 ;;correctly parsed as recovery token; the second line is correct.
88 (let ((r (doit (make-lexical-token 'NUMBER #f 1)
89 (make-lexical-token 'BAD #f 'alpha)
90 (make-lexical-token 'NEWLINE #f #\newline)
91 (make-lexical-token 'NUMBER #f 2)
92 (make-lexical-token 'NEWLINE #f #\newline))))
96 (error-handler "Syntax error: unexpected token : " . BAD)))
100 ;;The first BAD triggers an error, recovery happens skipping the
101 ;;second and third BADs, the first NEWLINE is detected as
102 ;;synchronisation token; the second line is correct.
103 (let ((r (doit (make-lexical-token 'NUMBER #f 1)
104 (make-lexical-token 'BAD #f 'alpha)
105 (make-lexical-token 'BAD #f 'beta)
106 (make-lexical-token 'BAD #f 'delta)
107 (make-lexical-token 'NEWLINE #f #\newline)
108 (make-lexical-token 'NUMBER #f 2)
109 (make-lexical-token 'NEWLINE #f #\newline))))
111 => '(((recover #f #f)
113 (error-handler "Syntax error: unexpected token : " . BAD)))
115 ;;; --------------------------------------------------------------------
116 ;;; Failed error recovery.
119 ;;End-of-input is found after NUMBER.
120 (let ((r (doit (make-lexical-token 'NUMBER #f 1))))
122 => '(#f (error-handler "Syntax error: unexpected end of input")))
125 ;;The BAD triggers the error, the stack is rewind up to the start,
126 ;;then end-of-input happens while trying to skip tokens until the
127 ;;synchronisation one is found. End-of-input is an acceptable token
129 (let ((r (doit (make-lexical-token 'NUMBER #f 1)
130 (make-lexical-token 'BAD #f 'alpha)
131 (make-lexical-token 'BAD #f 'beta)
132 (make-lexical-token 'BAD #f 'delta))))
134 => '(0 (error-handler "Syntax error: unexpected token : " . BAD)))
137 ;;The BAD triggers the error, the stack is rewind up to the start,
138 ;;then end-of-input happens while trying to skip tokens until the
139 ;;synchronisation one is found. End-of-input is an acceptable token
141 (let ((r (doit (make-lexical-token 'BAD #f 'alpha))))
143 => '(0 (error-handler "Syntax error: unexpected token : " . BAD)))