test-lr-error-recovery-01.scm 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. ;;; test-lr-error-recovery-01.scm --
  2. ;;
  3. ;;Test error recovery with a terminator terminal.
  4. ;;
  5. (load "common-test.scm")
  6. (define (doit . tokens)
  7. (let ((parser (lalr-parser
  8. (expect: 0)
  9. (NUMBER BAD NEWLINE)
  10. (script (lines) : (reverse $1)
  11. () : 0)
  12. (lines (lines line) : (cons $2 $1)
  13. (line) : (list $1))
  14. (line (NEWLINE) : (list 'line $1)
  15. (NUMBER NEWLINE) : (list 'line $1 $2)
  16. (NUMBER NUMBER NEWLINE) : (list 'line $1 $2 $3)
  17. ;;This semantic action will cause "(recover $1
  18. ;;$2)" to be the result of the offending line.
  19. (error NEWLINE) : (list 'recover $1 $2)))))
  20. (parser (make-lexer tokens) error-handler)))
  21. ;;; --------------------------------------------------------------------
  22. ;;; No errors, grammar tests.
  23. (check
  24. (doit)
  25. => 0)
  26. (check
  27. (doit (make-lexical-token 'NEWLINE #f #\newline))
  28. => '((line #\newline)))
  29. (check
  30. (doit (make-lexical-token 'NUMBER #f 1)
  31. (make-lexical-token 'NEWLINE #f #\newline))
  32. => '((line 1 #\newline)))
  33. (check
  34. (doit (make-lexical-token 'NUMBER #f 1)
  35. (make-lexical-token 'NUMBER #f 2)
  36. (make-lexical-token 'NEWLINE #f #\newline))
  37. => '((line 1 2 #\newline)))
  38. (check
  39. (doit (make-lexical-token 'NUMBER #f 1)
  40. (make-lexical-token 'NEWLINE #f #\newline)
  41. (make-lexical-token 'NUMBER #f 2)
  42. (make-lexical-token 'NEWLINE #f #\newline))
  43. => '((line 1 #\newline)
  44. (line 2 #\newline)))
  45. (check
  46. (doit (make-lexical-token 'NUMBER #f 1)
  47. (make-lexical-token 'NEWLINE #f #\newline)
  48. (make-lexical-token 'NUMBER #f 2)
  49. (make-lexical-token 'NEWLINE #f #\newline)
  50. (make-lexical-token 'NUMBER #f 3)
  51. (make-lexical-token 'NEWLINE #f #\newline))
  52. => '((line 1 #\newline)
  53. (line 2 #\newline)
  54. (line 3 #\newline)))
  55. (check
  56. (doit (make-lexical-token 'NUMBER #f 1)
  57. (make-lexical-token 'NEWLINE #f #\newline)
  58. (make-lexical-token 'NUMBER #f 2)
  59. (make-lexical-token 'NEWLINE #f #\newline)
  60. (make-lexical-token 'NUMBER #f 3)
  61. (make-lexical-token 'NEWLINE #f #\newline)
  62. (make-lexical-token 'NUMBER #f 41)
  63. (make-lexical-token 'NUMBER #f 42)
  64. (make-lexical-token 'NEWLINE #f #\newline))
  65. => '((line 1 #\newline)
  66. (line 2 #\newline)
  67. (line 3 #\newline)
  68. (line 41 42 #\newline)))
  69. ;;; --------------------------------------------------------------------
  70. ;;; Successful error recovery.
  71. (check
  72. ;;The BAD triggers an error, recovery happens, the first NEWLINE is
  73. ;;correctly parsed as recovery token; the second line is correct.
  74. (let ((r (doit (make-lexical-token 'NUMBER #f 1)
  75. (make-lexical-token 'BAD #f 'alpha)
  76. (make-lexical-token 'NEWLINE #f #\newline)
  77. (make-lexical-token 'NUMBER #f 2)
  78. (make-lexical-token 'NEWLINE #f #\newline))))
  79. (cons r *error*))
  80. => '(((recover #f #f)
  81. (line 2 #\newline))
  82. (error-handler "Syntax error: unexpected token : " . BAD)))
  83. (check
  84. ;;The first BAD triggers an error, recovery happens skipping the
  85. ;;second and third BADs, the first NEWLINE is detected as
  86. ;;synchronisation token; the second line is correct.
  87. (let ((r (doit (make-lexical-token 'NUMBER #f 1)
  88. (make-lexical-token 'BAD #f 'alpha)
  89. (make-lexical-token 'BAD #f 'beta)
  90. (make-lexical-token 'BAD #f 'delta)
  91. (make-lexical-token 'NEWLINE #f #\newline)
  92. (make-lexical-token 'NUMBER #f 2)
  93. (make-lexical-token 'NEWLINE #f #\newline))))
  94. (cons r *error*))
  95. => '(((recover #f #f)
  96. (line 2 #\newline))
  97. (error-handler "Syntax error: unexpected token : " . BAD)))
  98. ;;; --------------------------------------------------------------------
  99. ;;; Failed error recovery.
  100. (check
  101. ;;End-of-input is found after NUMBER.
  102. (let ((r (doit (make-lexical-token 'NUMBER #f 1))))
  103. (cons r *error*))
  104. => '(#f (error-handler "Syntax error: unexpected end of input")))
  105. (check
  106. ;;The BAD triggers the error, the stack is rewind up to the start,
  107. ;;then end-of-input happens while trying to skip tokens until the
  108. ;;synchronisation one is found. End-of-input is an acceptable token
  109. ;;after the start.
  110. (let ((r (doit (make-lexical-token 'NUMBER #f 1)
  111. (make-lexical-token 'BAD #f 'alpha)
  112. (make-lexical-token 'BAD #f 'beta)
  113. (make-lexical-token 'BAD #f 'delta))))
  114. (cons r *error*))
  115. => '(0 (error-handler "Syntax error: unexpected token : " . BAD)))
  116. (check
  117. ;;The BAD triggers the error, the stack is rewind up to the start,
  118. ;;then end-of-input happens while trying to skip tokens until the
  119. ;;synchronisation one is found. End-of-input is an acceptable token
  120. ;;after the start.
  121. (let ((r (doit (make-lexical-token 'BAD #f 'alpha))))
  122. (cons r *error*))
  123. => '(0 (error-handler "Syntax error: unexpected token : " . BAD)))
  124. ;;; end of file