@@ -38,22 +38,55 @@ public final class Parser {
3838
3939 private final List <Token > tokens ;
4040 private final int size ;
41+ private final ParseErrors parseErrors ;
4142
4243 private int pos ;
4344
4445 public Parser (List <Token > tokens ) {
4546 this .tokens = tokens ;
4647 size = tokens .size ();
48+ parseErrors = new ParseErrors ();
49+ }
50+
51+ public ParseErrors getParseErrors () {
52+ return parseErrors ;
4753 }
4854
4955 public Statement parse () {
56+ parseErrors .clear ();
5057 final BlockStatement result = new BlockStatement ();
5158 while (!match (TokenType .EOF )) {
52- result .add (statement ());
59+ try {
60+ result .add (statement ());
61+ } catch (Exception ex ) {
62+ parseErrors .add (ex , getErrorLine ());
63+ recover ();
64+ }
5365 }
5466 return result ;
5567 }
5668
69+ private int getErrorLine () {
70+ if (size == 0 ) return 0 ;
71+ if (pos >= size ) return tokens .get (size - 1 ).getRow ();
72+ return tokens .get (pos ).getRow ();
73+ }
74+
75+ private void recover () {
76+ int preRecoverPosition = pos ;
77+ for (int i = preRecoverPosition ; i < size ; i ++) {
78+ pos = i ;
79+ try {
80+ statement ();
81+ // successfully parsed,
82+ pos = i ; // restore position
83+ return ;
84+ } catch (Exception ex ) {
85+ // fail
86+ }
87+ }
88+ }
89+
5790 private Statement block () {
5891 final BlockStatement block = new BlockStatement ();
5992 consume (TokenType .LBRACE );
0 commit comments