inspirer / textmapper

Lexer and Parser generator
http://textmapper.org
MIT License
110 stars 25 forks source link

More debug messages in error recovery. #66

Open jdb opened 1 year ago

jdb commented 1 year ago

New error messages:

Here is an example output (new messages prefixed with a +):

$ parse_add '1; (2; 3;'
reduced to: file$1
shift: NUMBER (1)
reduced to: expr
reduced to: stmt
shift: ; (;)
reduced to: file$1
shift: ( (()
shift: NUMBER (2)
reduced to: expr
broke at ;
+ no error recovery on expr 
+ no error recovery on (
+ error recovery possible on file$1
+ no error recovery on EOI
+ possible recovery positions: EOI
trying to recover on ;
dropped from stack: expr
dropped from stack: (
recovered
reduced to: stmt
shift: ; (;)
reduced to: file$1
shift: NUMBER (3)
reduced to: expr
reduced to: stmt
shift: ; (;)
reduced to: file$1
reduced to: file
shift: EOI ()

«1; (2; 3;» File
  «1» Num
  «(2» SyntaxProblem
    «2» Num
  «3» Num

Here is a second example that reports the detection of the .recoveryScope:

$ parse_add '1; {2; 3;'
reduced to: file$1
shift: NUMBER (1)
reduced to: expr
reduced to: stmt
shift: ; (;)
reduced to: file$1
shift: { ({)
reduced to: block$1
shift: NUMBER (2)
reduced to: expr
reduced to: stmt
shift: ; (;)
reduced to: block$1
shift: NUMBER (3)
reduced to: expr
reduced to: stmt
shift: ; (;)
reduced to: block$1
broke at EOI
error recovery possible on block$1
+ found a .recoveryScope marker, confine error to block$1
+ possible recovery positions: EOI
trying to recover on EOI
2023/06/19 23:14:43 parse error: syntax error at line 1
2023/06/19 23:14:43 no AST tree produced.

This is for the toy grammar:

language add(go);
lang = "add"
package = "github.com/jdb/addlang/syntax"
eventBased = true 
eventAST = true 
eventFields = true 
debugParser  = true

:: lexer
NUMBER: /\d+/
'+' : /+/
'*' : /\*/
'(': /\(/
')': /\)/
'{': /\{/
'}': /\}/
';': /;/

error:

:: parser
%input file;
%left '+';
%left '*';

file -> File:
  ( stmt ';')*;

block -> Block:
   '{' ( .recoveryScope stmt ';')* '}' ;

stmt:
  expr
  | block
  | error  -> SyntaxProblem
  ;

%interface Expr;

expr -> Expr:
  NUMBER -> Num
  | expr '+' expr -> Add
  | expr '*' expr -> Multiply
  | '(' expr ')' -> ParenExpr
;

%%