123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- ;;; test-lr-error-recovery-01.scm --
- ;;
- ;;Test error recovery with a terminator terminal.
- ;;
- (load "common-test.scm")
- (define (doit . tokens)
- (let ((parser (lalr-parser
- (expect: 0)
- (NUMBER BAD NEWLINE)
- (script (lines) : (reverse $1)
- () : 0)
- (lines (lines line) : (cons $2 $1)
- (line) : (list $1))
- (line (NEWLINE) : (list 'line $1)
- (NUMBER NEWLINE) : (list 'line $1 $2)
- (NUMBER NUMBER NEWLINE) : (list 'line $1 $2 $3)
- ;;This semantic action will cause "(recover $1
- ;;$2)" to be the result of the offending line.
- (error NEWLINE) : (list 'recover $1 $2)))))
- (parser (make-lexer tokens) error-handler)))
- ;;; --------------------------------------------------------------------
- ;;; No errors, grammar tests.
- (check
- (doit)
- => 0)
- (check
- (doit (make-lexical-token 'NEWLINE #f #\newline))
- => '((line #\newline)))
- (check
- (doit (make-lexical-token 'NUMBER #f 1)
- (make-lexical-token 'NEWLINE #f #\newline))
- => '((line 1 #\newline)))
- (check
- (doit (make-lexical-token 'NUMBER #f 1)
- (make-lexical-token 'NUMBER #f 2)
- (make-lexical-token 'NEWLINE #f #\newline))
- => '((line 1 2 #\newline)))
- (check
- (doit (make-lexical-token 'NUMBER #f 1)
- (make-lexical-token 'NEWLINE #f #\newline)
- (make-lexical-token 'NUMBER #f 2)
- (make-lexical-token 'NEWLINE #f #\newline))
- => '((line 1 #\newline)
- (line 2 #\newline)))
- (check
- (doit (make-lexical-token 'NUMBER #f 1)
- (make-lexical-token 'NEWLINE #f #\newline)
- (make-lexical-token 'NUMBER #f 2)
- (make-lexical-token 'NEWLINE #f #\newline)
- (make-lexical-token 'NUMBER #f 3)
- (make-lexical-token 'NEWLINE #f #\newline))
- => '((line 1 #\newline)
- (line 2 #\newline)
- (line 3 #\newline)))
- (check
- (doit (make-lexical-token 'NUMBER #f 1)
- (make-lexical-token 'NEWLINE #f #\newline)
- (make-lexical-token 'NUMBER #f 2)
- (make-lexical-token 'NEWLINE #f #\newline)
- (make-lexical-token 'NUMBER #f 3)
- (make-lexical-token 'NEWLINE #f #\newline)
- (make-lexical-token 'NUMBER #f 41)
- (make-lexical-token 'NUMBER #f 42)
- (make-lexical-token 'NEWLINE #f #\newline))
- => '((line 1 #\newline)
- (line 2 #\newline)
- (line 3 #\newline)
- (line 41 42 #\newline)))
- ;;; --------------------------------------------------------------------
- ;;; Successful error recovery.
- (check
- ;;The BAD triggers an error, recovery happens, the first NEWLINE is
- ;;correctly parsed as recovery token; the second line is correct.
- (let ((r (doit (make-lexical-token 'NUMBER #f 1)
- (make-lexical-token 'BAD #f 'alpha)
- (make-lexical-token 'NEWLINE #f #\newline)
- (make-lexical-token 'NUMBER #f 2)
- (make-lexical-token 'NEWLINE #f #\newline))))
- (cons r *error*))
- => '(((recover #f #f)
- (line 2 #\newline))
- (error-handler "Syntax error: unexpected token : " . BAD)))
- (check
- ;;The first BAD triggers an error, recovery happens skipping the
- ;;second and third BADs, the first NEWLINE is detected as
- ;;synchronisation token; the second line is correct.
- (let ((r (doit (make-lexical-token 'NUMBER #f 1)
- (make-lexical-token 'BAD #f 'alpha)
- (make-lexical-token 'BAD #f 'beta)
- (make-lexical-token 'BAD #f 'delta)
- (make-lexical-token 'NEWLINE #f #\newline)
- (make-lexical-token 'NUMBER #f 2)
- (make-lexical-token 'NEWLINE #f #\newline))))
- (cons r *error*))
- => '(((recover #f #f)
- (line 2 #\newline))
- (error-handler "Syntax error: unexpected token : " . BAD)))
- ;;; --------------------------------------------------------------------
- ;;; Failed error recovery.
- (check
- ;;End-of-input is found after NUMBER.
- (let ((r (doit (make-lexical-token 'NUMBER #f 1))))
- (cons r *error*))
- => '(#f (error-handler "Syntax error: unexpected end of input")))
- (check
- ;;The BAD triggers the error, the stack is rewind up to the start,
- ;;then end-of-input happens while trying to skip tokens until the
- ;;synchronisation one is found. End-of-input is an acceptable token
- ;;after the start.
- (let ((r (doit (make-lexical-token 'NUMBER #f 1)
- (make-lexical-token 'BAD #f 'alpha)
- (make-lexical-token 'BAD #f 'beta)
- (make-lexical-token 'BAD #f 'delta))))
- (cons r *error*))
- => '(0 (error-handler "Syntax error: unexpected token : " . BAD)))
- (check
- ;;The BAD triggers the error, the stack is rewind up to the start,
- ;;then end-of-input happens while trying to skip tokens until the
- ;;synchronisation one is found. End-of-input is an acceptable token
- ;;after the start.
- (let ((r (doit (make-lexical-token 'BAD #f 'alpha))))
- (cons r *error*))
- => '(0 (error-handler "Syntax error: unexpected token : " . BAD)))
- ;;; end of file
|