error tolerant parsing
This commit is contained in:
		
							parent
							
								
									ebe06da6e0
								
							
						
					
					
						commit
						83a1400a4f
					
				
							
								
								
									
										31
									
								
								errors/error.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								errors/error.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,31 @@ | ||||
| package errors | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 
 | ||||
| 	"github.com/z7zmey/php-parser/position" | ||||
| 	"github.com/z7zmey/php-parser/token" | ||||
| ) | ||||
| 
 | ||||
| // Error parsing error | ||||
| type Error struct { | ||||
| 	Msg string | ||||
| 	Pos position.Position | ||||
| } | ||||
| 
 | ||||
| // NewError creates and returns new Error | ||||
| func NewError(msg string, t token.Token) *Error { | ||||
| 	return &Error{ | ||||
| 		Msg: msg, | ||||
| 		Pos: position.Position{ | ||||
| 			StartLine: t.StartLine, | ||||
| 			EndLine:   t.EndLine, | ||||
| 			StartPos:  t.StartPos, | ||||
| 			EndPos:    t.EndPos, | ||||
| 		}, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (e *Error) String() string { | ||||
| 	return fmt.Sprintf("%s at line %d", e.Msg, e.Pos.StartLine) | ||||
| } | ||||
							
								
								
									
										10
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								main.go
									
									
									
									
									
								
							| @ -9,6 +9,7 @@ import ( | ||||
| 
 | ||||
| 	"github.com/yookoala/realpath" | ||||
| 	"github.com/z7zmey/php-parser/comment" | ||||
| 	"github.com/z7zmey/php-parser/errors" | ||||
| 	"github.com/z7zmey/php-parser/node" | ||||
| 	"github.com/z7zmey/php-parser/php5" | ||||
| 	"github.com/z7zmey/php-parser/php7" | ||||
| @ -20,6 +21,7 @@ func main() { | ||||
| 	var nodes node.Node | ||||
| 	var comments comment.Comments | ||||
| 	var positions position.Positions | ||||
| 	var errors []*errors.Error | ||||
| 
 | ||||
| 	usePhp5 := flag.Bool("php5", false, "use PHP5 parser") | ||||
| 	flag.Parse() | ||||
| @ -34,9 +36,13 @@ func main() { | ||||
| 
 | ||||
| 				src, _ := os.Open(string(path)) | ||||
| 				if *usePhp5 { | ||||
| 					nodes, comments, positions = php5.Parse(src, path) | ||||
| 					nodes, comments, positions, errors = php5.Parse(src, path) | ||||
| 				} else { | ||||
| 					nodes, comments, positions = php7.Parse(src, path) | ||||
| 					nodes, comments, positions, errors = php7.Parse(src, path) | ||||
| 				} | ||||
| 
 | ||||
| 				for _, e := range errors { | ||||
| 					fmt.Println(e) | ||||
| 				} | ||||
| 
 | ||||
| 				nsResolver := visitor.NewNamespaceResolver() | ||||
|  | ||||
| @ -7,16 +7,26 @@ import ( | ||||
| 
 | ||||
| 	"github.com/cznic/golex/lex" | ||||
| 
 | ||||
| 	"github.com/z7zmey/php-parser/errors" | ||||
| 	"github.com/z7zmey/php-parser/scanner" | ||||
| 	"github.com/z7zmey/php-parser/token" | ||||
| ) | ||||
| 
 | ||||
| type lexer struct { | ||||
| 	scanner.Lexer | ||||
| 	lastToken *token.Token | ||||
| 	errors    []*errors.Error | ||||
| } | ||||
| 
 | ||||
| func (l *lexer) Lex(lval *yySymType) int { | ||||
| 	return l.Lexer.Lex(lval) | ||||
| 	t := l.Lexer.Lex(lval) | ||||
| 	l.lastToken = &lval.token | ||||
| 
 | ||||
| 	return t | ||||
| } | ||||
| 
 | ||||
| func (l *lexer) Error(msg string) { | ||||
| 	l.errors = append(l.errors, errors.NewError(msg, *l.lastToken)) | ||||
| } | ||||
| 
 | ||||
| func (lval *yySymType) Token(t token.Token) { | ||||
| @ -30,12 +40,16 @@ func newLexer(src io.Reader, fName string) *lexer { | ||||
| 		panic(err) | ||||
| 	} | ||||
| 
 | ||||
| 	return &lexer{ | ||||
| 		scanner.Lexer{ | ||||
| 	scanner := scanner.Lexer{ | ||||
| 		Lexer:         lx, | ||||
| 		StateStack:    []int{0}, | ||||
| 		PhpDocComment: "", | ||||
| 		Comments:      nil, | ||||
| 		}, | ||||
| 	} | ||||
| 
 | ||||
| 	return &lexer{ | ||||
| 		scanner, | ||||
| 		nil, | ||||
| 		nil, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -4,6 +4,7 @@ package php5 | ||||
| import ( | ||||
| 	"io" | ||||
| 
 | ||||
| 	"github.com/z7zmey/php-parser/errors" | ||||
| 	"github.com/z7zmey/php-parser/node/expr" | ||||
| 
 | ||||
| 	"github.com/z7zmey/php-parser/comment" | ||||
| @ -21,15 +22,17 @@ var positionBuilder position.Builder | ||||
| var parentNode node.Node | ||||
| 
 | ||||
| // Parse the php5 parser entrypoint | ||||
| func Parse(src io.Reader, fName string) (node.Node, comment.Comments, position.Positions) { | ||||
| func Parse(src io.Reader, fName string) (node.Node, comment.Comments, position.Positions, []*errors.Error) { | ||||
| 	yyDebug = 0 | ||||
| 	yyErrorVerbose = true | ||||
| 	rootnode = stmt.NewStmtList([]node.Node{}) //reset | ||||
| 	comments = comment.Comments{} | ||||
| 	positions = position.Positions{} | ||||
| 	positionBuilder = position.Builder{Positions: &positions} | ||||
| 	yyParse(newLexer(src, fName)) | ||||
| 	return rootnode, comments, positions | ||||
| 
 | ||||
| 	lexer := newLexer(src, fName) | ||||
| 	yyParse(lexer) | ||||
| 	return rootnode, comments, positions, lexer.errors | ||||
| } | ||||
| 
 | ||||
| // ListGetFirstNodeComments returns comments of a first node in the list | ||||
|  | ||||
							
								
								
									
										5598
									
								
								php5/php5.go
									
									
									
									
									
								
							
							
						
						
									
										5598
									
								
								php5/php5.go
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										27
									
								
								php5/php5.y
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								php5/php5.y
									
									
									
									
									
								
							| @ -239,7 +239,12 @@ start: | ||||
| ; | ||||
| 
 | ||||
| top_statement_list: | ||||
|         top_statement_list top_statement                { $$ = append($1, $2) } | ||||
|         top_statement_list top_statement | ||||
|             { | ||||
|                 if $2 != nil { | ||||
|                     $$ = append($1, $2) | ||||
|                 } | ||||
|             } | ||||
|     |   /* empty */                                     { $$ = []node.Node{} } | ||||
| ; | ||||
| 
 | ||||
| @ -261,7 +266,12 @@ namespace_name: | ||||
| ; | ||||
| 
 | ||||
| top_statement: | ||||
|         statement | ||||
|         error | ||||
|             { | ||||
|                 // error | ||||
|                 $$ = nil | ||||
|             } | ||||
|     |   statement | ||||
|             { $$ = $1 } | ||||
|     |   function_declaration_statement | ||||
|             { $$ = $1 } | ||||
| @ -534,14 +544,23 @@ constant_declaration: | ||||
| 
 | ||||
| inner_statement_list: | ||||
|         inner_statement_list inner_statement | ||||
|             { $$ = append($1, $2) } | ||||
|             { | ||||
|                 if $2 != nil { | ||||
|                     $$ = append($1, $2) | ||||
|                 } | ||||
|             } | ||||
|     |   /* empty */ | ||||
|             { $$ = []node.Node{} } | ||||
| ; | ||||
| 
 | ||||
| 
 | ||||
| inner_statement: | ||||
|         statement | ||||
|         error | ||||
|             { | ||||
|                 // error | ||||
|                 $$ = nil | ||||
|             } | ||||
|     |   statement | ||||
|             { $$ = $1 } | ||||
|     |   function_declaration_statement | ||||
|             { $$ = $1 } | ||||
|  | ||||
| @ -7,16 +7,26 @@ import ( | ||||
| 
 | ||||
| 	"github.com/cznic/golex/lex" | ||||
| 
 | ||||
| 	"github.com/z7zmey/php-parser/errors" | ||||
| 	"github.com/z7zmey/php-parser/scanner" | ||||
| 	"github.com/z7zmey/php-parser/token" | ||||
| ) | ||||
| 
 | ||||
| type lexer struct { | ||||
| 	scanner.Lexer | ||||
| 	lastToken *token.Token | ||||
| 	errors    []*errors.Error | ||||
| } | ||||
| 
 | ||||
| func (l *lexer) Lex(lval *yySymType) int { | ||||
| 	return l.Lexer.Lex(lval) | ||||
| 	t := l.Lexer.Lex(lval) | ||||
| 	l.lastToken = &lval.token | ||||
| 
 | ||||
| 	return t | ||||
| } | ||||
| 
 | ||||
| func (l *lexer) Error(msg string) { | ||||
| 	l.errors = append(l.errors, errors.NewError(msg, *l.lastToken)) | ||||
| } | ||||
| 
 | ||||
| func (lval *yySymType) Token(t token.Token) { | ||||
| @ -30,12 +40,16 @@ func newLexer(src io.Reader, fName string) *lexer { | ||||
| 		panic(err) | ||||
| 	} | ||||
| 
 | ||||
| 	return &lexer{ | ||||
| 		scanner.Lexer{ | ||||
| 	scanner := scanner.Lexer{ | ||||
| 		Lexer:         lx, | ||||
| 		StateStack:    []int{0}, | ||||
| 		PhpDocComment: "", | ||||
| 		Comments:      nil, | ||||
| 		}, | ||||
| 	} | ||||
| 
 | ||||
| 	return &lexer{ | ||||
| 		scanner, | ||||
| 		nil, | ||||
| 		nil, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -5,6 +5,7 @@ import ( | ||||
| 	"io" | ||||
| 
 | ||||
| 	"github.com/z7zmey/php-parser/comment" | ||||
| 	"github.com/z7zmey/php-parser/errors" | ||||
| 	"github.com/z7zmey/php-parser/node" | ||||
| 	"github.com/z7zmey/php-parser/node/stmt" | ||||
| 	"github.com/z7zmey/php-parser/position" | ||||
| @ -17,15 +18,17 @@ var positions position.Positions | ||||
| var positionBuilder position.Builder | ||||
| 
 | ||||
| // Parse the php7 parser entrypoint | ||||
| func Parse(src io.Reader, fName string) (node.Node, comment.Comments, position.Positions) { | ||||
| func Parse(src io.Reader, fName string) (node.Node, comment.Comments, position.Positions, []*errors.Error) { | ||||
| 	yyDebug = 0 | ||||
| 	yyErrorVerbose = true | ||||
| 	rootnode = stmt.NewStmtList([]node.Node{}) //reset | ||||
| 	comments = comment.Comments{} | ||||
| 	positions = position.Positions{} | ||||
| 	positionBuilder = position.Builder{&positions} | ||||
| 	yyParse(newLexer(src, fName)) | ||||
| 	return rootnode, comments, positions | ||||
| 
 | ||||
| 	lexer := newLexer(src, fName) | ||||
| 	yyParse(lexer) | ||||
| 	return rootnode, comments, positions, lexer.errors | ||||
| } | ||||
| 
 | ||||
| // ListGetFirstNodeComments returns comments of a first node in the list | ||||
|  | ||||
							
								
								
									
										4588
									
								
								php7/php7.go
									
									
									
									
									
								
							
							
						
						
									
										4588
									
								
								php7/php7.go
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										28
									
								
								php7/php7.y
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								php7/php7.y
									
									
									
									
									
								
							| @ -281,7 +281,12 @@ identifier: | ||||
| ; | ||||
| 
 | ||||
| top_statement_list: | ||||
|         top_statement_list top_statement                { $$ = append($1, $2) } | ||||
|     top_statement_list top_statement | ||||
|         { | ||||
|             if $2 != nil { | ||||
|                 $$ = append($1, $2) | ||||
|             } | ||||
|         } | ||||
|     |   /* empty */                                     { $$ = []node.Node{} } | ||||
| ; | ||||
| 
 | ||||
| @ -324,7 +329,12 @@ name: | ||||
| ; | ||||
| 
 | ||||
| top_statement: | ||||
|         statement                                       { $$ = $1; } | ||||
|     error | ||||
|         { | ||||
|             // error | ||||
|             $$ = nil | ||||
|         } | ||||
|     |   statement                                       { $$ = $1; } | ||||
|     |   function_declaration_statement                  { $$ = $1; } | ||||
|     |   class_declaration_statement                     { $$ = $1; } | ||||
|     |   trait_declaration_statement                     { $$ = $1; } | ||||
| @ -498,12 +508,22 @@ const_list: | ||||
| ; | ||||
| 
 | ||||
| inner_statement_list: | ||||
|         inner_statement_list inner_statement            { $$ = append($1, $2) } | ||||
|     inner_statement_list inner_statement | ||||
|         { | ||||
|             if $2 != nil { | ||||
|                 $$ = append($1, $2) | ||||
|             } | ||||
|         } | ||||
|     |   /* empty */                                     { $$ = []node.Node{} } | ||||
| ; | ||||
| 
 | ||||
| inner_statement: | ||||
|     statement                                           { $$ = $1; } | ||||
|     error | ||||
|         { | ||||
|             // error | ||||
|             $$ = nil | ||||
|         } | ||||
|     |   statement                                       { $$ = $1; } | ||||
|     |   function_declaration_statement                  { $$ = $1; } | ||||
|     |   class_declaration_statement                     { $$ = $1; } | ||||
|     |   trait_declaration_statement                     { $$ = $1; } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user