@@ -6,6 +6,16 @@ function get_last_error(state) {
66 var last_exp_position = state . lastExpectations . reduce ( function ( a , b ) {
77 return Math . max ( a , b . position ) ;
88 } , state . position ) ;
9+ var dedupedExpectations = state . lastExpectations . filter ( function ( expectation ) {
10+ return expectation . position === last_exp_position ;
11+ } ) . filter ( function ( expectation , index , array ) {
12+ for ( var i = 0 ; i < array . length ; i ++ ) {
13+ if ( array [ i ] . rule === expectation . rule && i !== index ) {
14+ return false ;
15+ }
16+ }
17+ return true ;
18+ } ) ;
919
1020 var last_position = 0 ;
1121 var line_of_error = '' ;
@@ -33,7 +43,7 @@ function get_last_error(state) {
3343 unexpected_char = state . text [ last_exp_position ] ;
3444 }
3545 var unexpected = 'Unexpected "' + unexpected_char + '"' ;
36- var expected_rules = state . lastExpectations . map ( function ( exp ) { return exp . rule } ) ;
46+ var expected_rules = dedupedExpectations . map ( function ( exp ) { return exp . rule } ) ;
3747 var expected = ' expected (' + expected_rules . join ( ' or ' ) + ')' ;
3848 var pointer = ( new Array ( position_of_error + 3 + error_ln_length ) ) . join ( '-' ) + '^' ;
3949 var extra = line_of_error + '\n' + pointer ;
@@ -88,16 +98,20 @@ function regex_char(rule) {
8898function sequence ( parsers ) {
8999 return function ( state ) {
90100 var asts = [ ] ;
101+ var expectations = [ ] ;
91102 var start_position = state . position ;
92103 for ( var i = 0 ; i < parsers . length ; i ++ ) {
93104 var ast = parsers [ i ] ( state ) ;
105+ expectations = expectations . concat ( state . lastExpectations ) ;
94106 if ( ast ) {
95107 asts . push ( ast ) ;
96108 } else {
109+ state . lastExpectations = expectations ;
97110 return false ;
98111 }
99112 }
100113 var match = asts . reduce ( function ( r , n ) { return r + ( n . match || '' ) } , '' ) ;
114+ state . lastExpectations = expectations ;
101115 return {
102116 type : 'sequence' ,
103117 match : match ,
@@ -170,7 +184,7 @@ function one_or_more(parser) {
170184 var state_position = state . position ;
171185 ast = parser ( state ) ;
172186 if ( ast ) {
173- asts . push ( ast ) ;
187+ asts . push ( ast ) ;
174188 } else {
175189 state . position = state_position ;
176190 }
@@ -197,6 +211,8 @@ function optional(parser) {
197211 var asts = [ ] ;
198212 if ( ast ) {
199213 asts . push ( ast ) ;
214+ } else {
215+ state . position = start_position ;
200216 }
201217 var match = asts . reduce ( function ( r , n ) { return r + ( n . match || '' ) } , '' ) ;
202218 return {
@@ -247,7 +263,7 @@ function not_predicate(parser) {
247263 children : [ ast ] ,
248264 position : state . position
249265 } ] ;
250- return false ;
266+ return false ;
251267 } else {
252268 state . lastExpectations = [ ] ;
253269 return {
@@ -264,6 +280,7 @@ function not_predicate(parser) {
264280function end_of_file ( ) {
265281 return function ( state ) {
266282 if ( state . text . length === state . position ) {
283+ state . lastExpectations = [ ] ;
267284 return {
268285 type : 'end_of_file' ,
269286 match : null ,
@@ -272,11 +289,11 @@ function end_of_file() {
272289 end_position : state . position
273290 }
274291 } else {
275- state . lastExpectations . push ( {
292+ state . lastExpectations = [ {
276293 type : 'end_of_file' ,
277294 rule : 'EOF' ,
278295 position : state . position
279- } ) ;
296+ } ] ;
280297 return false ;
281298 }
282299 }
0 commit comments