[refactoring] parsing error handler

This commit is contained in:
Vadym Slizov 2020-06-29 23:00:56 +03:00
parent 424f7a132c
commit d7652b1c7f
12 changed files with 1191 additions and 631 deletions

View File

@ -15,8 +15,10 @@ import (
"github.com/pkg/profile" "github.com/pkg/profile"
"github.com/yookoala/realpath" "github.com/yookoala/realpath"
"github.com/z7zmey/php-parser/pkg/ast"
"github.com/z7zmey/php-parser/pkg/ast/traverser" "github.com/z7zmey/php-parser/pkg/ast/traverser"
"github.com/z7zmey/php-parser/pkg/ast/visitor" "github.com/z7zmey/php-parser/pkg/ast/visitor"
"github.com/z7zmey/php-parser/pkg/errors"
"github.com/z7zmey/php-parser/pkg/parser" "github.com/z7zmey/php-parser/pkg/parser"
"github.com/z7zmey/php-parser/pkg/printer" "github.com/z7zmey/php-parser/pkg/printer"
) )
@ -37,8 +39,9 @@ type file struct {
} }
type result struct { type result struct {
path string path string
parser parser.Parser rootNode ast.Vertex
errors []*errors.Error
} }
func main() { func main() {
@ -121,14 +124,18 @@ func parserWorker(fileCh <-chan *file, r chan<- result) {
return return
} }
parserWorker, err := parser.NewParser(f.content, phpVersion, *withFreeFloating) parserErrors := []*errors.Error{}
cfg := parser.Config{
ErrorHandlerFunc: func(e *errors.Error) {
parserErrors = append(parserErrors, e)
},
}
rootNode, err := parser.Parse(f.content, phpVersion, cfg)
if err != nil { if err != nil {
panic(err.Error()) panic(err.Error())
} }
parserWorker.Parse() r <- result{path: f.path, rootNode: rootNode, errors: parserErrors}
r <- result{path: f.path, parser: parserWorker}
} }
} }
@ -147,14 +154,14 @@ func printerWorker(r <-chan result) {
fmt.Fprintf(os.Stdout, "==> [%d] %s\n", counter, res.path) fmt.Fprintf(os.Stdout, "==> [%d] %s\n", counter, res.path)
} }
for _, e := range res.parser.GetErrors() { for _, e := range res.errors {
fmt.Fprintf(os.Stdout, "==> %s\n", e) fmt.Fprintf(os.Stdout, "==> %s\n", e)
} }
if *printBack { if *printBack {
o := bytes.NewBuffer([]byte{}) o := bytes.NewBuffer([]byte{})
p := printer.NewPrinter(o) p := printer.NewPrinter(o)
p.Print(res.parser.GetRootNode()) p.Print(res.rootNode)
err := ioutil.WriteFile(res.path, o.Bytes(), 0644) err := ioutil.WriteFile(res.path, o.Bytes(), 0644)
checkErr(err) checkErr(err)
@ -163,14 +170,14 @@ func printerWorker(r <-chan result) {
if *showResolvedNs { if *showResolvedNs {
v := visitor.NewNamespaceResolver() v := visitor.NewNamespaceResolver()
t := traverser.NewDFS(v) t := traverser.NewDFS(v)
t.Traverse(res.parser.GetRootNode()) t.Traverse(res.rootNode)
fmt.Printf("%+v", v.ResolvedNames) fmt.Printf("%+v", v.ResolvedNames)
} }
if *dump == true { if *dump == true {
v := visitor.NewDump(os.Stdout) v := visitor.NewDump(os.Stdout)
t := traverser.NewDFS(v) t := traverser.NewDFS(v)
t.Traverse(res.parser.GetRootNode()) t.Traverse(res.rootNode)
} }
wg.Done() wg.Done()

View File

@ -12,25 +12,20 @@ import (
// Parser structure // Parser structure
type Parser struct { type Parser struct {
Lexer *scanner.Lexer Lexer *scanner.Lexer
currentToken *scanner.Token currentToken *scanner.Token
rootNode ast.Vertex rootNode ast.Vertex
errors []*errors.Error withTokens bool
withTokens bool errHandlerFunc func(*errors.Error)
} }
// NewParser creates and returns new Parser // NewParser creates and returns new Parser
func NewParser(src []byte, v string, withTokens bool) *Parser { func NewParser(lexer *scanner.Lexer, withTokens bool, errHandlerFunc func(*errors.Error)) *Parser {
parser := &Parser{ return &Parser{
withTokens: withTokens, withTokens: withTokens,
Lexer: lexer,
errHandlerFunc: errHandlerFunc,
} }
lexer := scanner.NewLexer(src, v, withTokens, func(e *errors.Error) {
parser.errors = append(parser.errors, e)
})
parser.Lexer = lexer
return parser
} }
// Lex proxy to scanner Lex // Lex proxy to scanner Lex
@ -45,23 +40,12 @@ func (p *Parser) Lex(lval *yySymType) int {
func (p *Parser) Error(msg string) { func (p *Parser) Error(msg string) {
var pos = p.currentToken.Position var pos = p.currentToken.Position
p.errHandlerFunc(errors.NewError(msg, &pos))
p.errors = append(p.errors, errors.NewError(msg, &pos))
}
// GetErrors returns errors list
func (p *Parser) GetErrors() []*errors.Error {
return p.errors
} }
// Parse the php7 Parser entrypoint // Parse the php7 Parser entrypoint
func (p *Parser) Parse() int { func (p *Parser) Parse() int {
// init
p.errors = nil
p.rootNode = nil p.rootNode = nil
// parse
return yyParse(p) return yyParse(p)
} }

File diff suppressed because it is too large Load Diff

View File

@ -4,6 +4,7 @@ import (
"testing" "testing"
"github.com/z7zmey/php-parser/internal/php5" "github.com/z7zmey/php-parser/internal/php5"
"github.com/z7zmey/php-parser/internal/scanner"
) )
func BenchmarkPhp5(b *testing.B) { func BenchmarkPhp5(b *testing.B) {
@ -413,7 +414,8 @@ CAD;
` `
for n := 0; n < b.N; n++ { for n := 0; n < b.N; n++ {
php5parser := php5.NewParser([]byte(src), "5.6", false) lexer := scanner.NewLexer([]byte(src), "5.6", false, nil)
php5parser := php5.NewParser(lexer, false, nil)
php5parser.Parse() php5parser.Parse()
} }
} }

View File

@ -1,10 +1,12 @@
package php5_test package php5_test
import ( import (
"gotest.tools/assert"
"testing" "testing"
"gotest.tools/assert"
"github.com/z7zmey/php-parser/internal/php5" "github.com/z7zmey/php-parser/internal/php5"
"github.com/z7zmey/php-parser/internal/scanner"
"github.com/z7zmey/php-parser/pkg/ast" "github.com/z7zmey/php-parser/pkg/ast"
"github.com/z7zmey/php-parser/pkg/errors" "github.com/z7zmey/php-parser/pkg/errors"
"github.com/z7zmey/php-parser/pkg/position" "github.com/z7zmey/php-parser/pkg/position"
@ -22455,7 +22457,8 @@ func TestPhp5(t *testing.T) {
}, },
} }
php5parser := php5.NewParser([]byte(src), "5.6", false) lexer := scanner.NewLexer([]byte(src), "5.6", false, nil)
php5parser := php5.NewParser(lexer, false, nil)
php5parser.Parse() php5parser.Parse()
actual := php5parser.GetRootNode() actual := php5parser.GetRootNode()
assert.DeepEqual(t, expected, actual) assert.DeepEqual(t, expected, actual)
@ -22592,7 +22595,8 @@ func TestPhp5Strings(t *testing.T) {
}, },
} }
php5parser := php5.NewParser([]byte(src), "5.6", false) lexer := scanner.NewLexer([]byte(src), "5.6", false, nil)
php5parser := php5.NewParser(lexer, false, nil)
php5parser.Parse() php5parser.Parse()
actual := php5parser.GetRootNode() actual := php5parser.GetRootNode()
assert.DeepEqual(t, expected, actual) assert.DeepEqual(t, expected, actual)
@ -22818,7 +22822,8 @@ CAD;
}, },
} }
php5parser := php5.NewParser([]byte(src), "5.6", false) lexer := scanner.NewLexer([]byte(src), "5.6", false, nil)
php5parser := php5.NewParser(lexer, false, nil)
php5parser.Parse() php5parser.Parse()
actual := php5parser.GetRootNode() actual := php5parser.GetRootNode()
assert.DeepEqual(t, expected, actual) assert.DeepEqual(t, expected, actual)
@ -22838,8 +22843,13 @@ func TestPhp5ControlCharsErrors(t *testing.T) {
}, },
} }
php5parser := php5.NewParser([]byte(src), "5.6", false) parserErrors := []*errors.Error{}
errorHandlerFunc := func(e *errors.Error) {
parserErrors = append(parserErrors, e)
}
lexer := scanner.NewLexer([]byte(src), "5.6", false, errorHandlerFunc)
php5parser := php5.NewParser(lexer, false, errorHandlerFunc)
php5parser.Parse() php5parser.Parse()
actual := php5parser.GetErrors() assert.DeepEqual(t, expected, parserErrors)
assert.DeepEqual(t, expected, actual)
} }

View File

@ -11,25 +11,20 @@ import (
// Parser structure // Parser structure
type Parser struct { type Parser struct {
Lexer *scanner.Lexer Lexer *scanner.Lexer
currentToken *scanner.Token currentToken *scanner.Token
rootNode ast.Vertex rootNode ast.Vertex
errors []*errors.Error withTokens bool
withTokens bool errHandlerFunc func(*errors.Error)
} }
// NewParser creates and returns new Parser // NewParser creates and returns new Parser
func NewParser(src []byte, v string, withTokens bool) *Parser { func NewParser(lexer *scanner.Lexer, withTokens bool, errHandlerFunc func(*errors.Error)) *Parser {
parser := &Parser{ return &Parser{
withTokens: withTokens, withTokens: withTokens,
Lexer: lexer,
errHandlerFunc: errHandlerFunc,
} }
lexer := scanner.NewLexer(src, v, withTokens, func(e *errors.Error) {
parser.errors = append(parser.errors, e)
})
parser.Lexer = lexer
return parser
} }
func (p *Parser) Lex(lval *yySymType) int { func (p *Parser) Lex(lval *yySymType) int {
@ -43,23 +38,13 @@ func (p *Parser) Lex(lval *yySymType) int {
func (p *Parser) Error(msg string) { func (p *Parser) Error(msg string) {
var pos = p.currentToken.Position var pos = p.currentToken.Position
p.errHandlerFunc(errors.NewError(msg, &pos))
p.errors = append(p.errors, errors.NewError(msg, &pos))
}
// GetErrors returns errors list
func (p *Parser) GetErrors() []*errors.Error {
return p.errors
} }
// Parse the php7 Parser entrypoint // Parse the php7 Parser entrypoint
func (p *Parser) Parse() int { func (p *Parser) Parse() int {
// init
p.errors = nil
p.rootNode = nil p.rootNode = nil
// parse
return yyParse(p) return yyParse(p)
} }

File diff suppressed because it is too large Load Diff

View File

@ -4,6 +4,7 @@ import (
"testing" "testing"
"github.com/z7zmey/php-parser/internal/php7" "github.com/z7zmey/php-parser/internal/php7"
"github.com/z7zmey/php-parser/internal/scanner"
) )
func BenchmarkPhp7(b *testing.B) { func BenchmarkPhp7(b *testing.B) {
@ -381,7 +382,8 @@ CAD;
` `
for n := 0; n < b.N; n++ { for n := 0; n < b.N; n++ {
php7parser := php7.NewParser([]byte(src), "7.4", false) lexer := scanner.NewLexer([]byte(src), "7.4", false, nil)
php7parser := php7.NewParser(lexer, false, nil)
php7parser.Parse() php7parser.Parse()
} }
} }

View File

@ -6,6 +6,7 @@ import (
"gotest.tools/assert" "gotest.tools/assert"
"github.com/z7zmey/php-parser/internal/php7" "github.com/z7zmey/php-parser/internal/php7"
"github.com/z7zmey/php-parser/internal/scanner"
"github.com/z7zmey/php-parser/pkg/ast" "github.com/z7zmey/php-parser/pkg/ast"
"github.com/z7zmey/php-parser/pkg/errors" "github.com/z7zmey/php-parser/pkg/errors"
"github.com/z7zmey/php-parser/pkg/position" "github.com/z7zmey/php-parser/pkg/position"
@ -19633,7 +19634,8 @@ func TestPhp7(t *testing.T) {
}, },
} }
php7parser := php7.NewParser([]byte(src), "7.4", false) lexer := scanner.NewLexer([]byte(src), "7.4", false, nil)
php7parser := php7.NewParser(lexer, false, nil)
php7parser.Parse() php7parser.Parse()
actual := php7parser.GetRootNode() actual := php7parser.GetRootNode()
assert.DeepEqual(t, expected, actual) assert.DeepEqual(t, expected, actual)
@ -19770,7 +19772,8 @@ func TestPhp5Strings(t *testing.T) {
}, },
} }
php7parser := php7.NewParser([]byte(src), "7.4", false) lexer := scanner.NewLexer([]byte(src), "7.4", false, nil)
php7parser := php7.NewParser(lexer, false, nil)
php7parser.Parse() php7parser.Parse()
actual := php7parser.GetRootNode() actual := php7parser.GetRootNode()
assert.DeepEqual(t, expected, actual) assert.DeepEqual(t, expected, actual)
@ -19996,7 +19999,8 @@ CAD;
}, },
} }
php7parser := php7.NewParser([]byte(src), "7.4", false) lexer := scanner.NewLexer([]byte(src), "7.4", false, nil)
php7parser := php7.NewParser(lexer, false, nil)
php7parser.Parse() php7parser.Parse()
actual := php7parser.GetRootNode() actual := php7parser.GetRootNode()
assert.DeepEqual(t, expected, actual) assert.DeepEqual(t, expected, actual)
@ -20016,8 +20020,13 @@ func TestPhp7ControlCharsErrors(t *testing.T) {
}, },
} }
php7parser := php7.NewParser([]byte(src), "7.4", false) parserErrors := []*errors.Error{}
errorHandlerFunc := func(e *errors.Error) {
parserErrors = append(parserErrors, e)
}
lexer := scanner.NewLexer([]byte(src), "7.4", false, errorHandlerFunc)
php7parser := php7.NewParser(lexer, false, errorHandlerFunc)
php7parser.Parse() php7parser.Parse()
actual := php7parser.GetErrors() assert.DeepEqual(t, expected, parserErrors)
assert.DeepEqual(t, expected, actual)
} }

View File

@ -3,6 +3,7 @@ package parser
import ( import (
"github.com/z7zmey/php-parser/internal/php5" "github.com/z7zmey/php-parser/internal/php5"
"github.com/z7zmey/php-parser/internal/php7" "github.com/z7zmey/php-parser/internal/php7"
"github.com/z7zmey/php-parser/internal/scanner"
"github.com/z7zmey/php-parser/internal/version" "github.com/z7zmey/php-parser/internal/version"
"github.com/z7zmey/php-parser/pkg/ast" "github.com/z7zmey/php-parser/pkg/ast"
"github.com/z7zmey/php-parser/pkg/errors" "github.com/z7zmey/php-parser/pkg/errors"
@ -12,22 +13,31 @@ import (
type Parser interface { type Parser interface {
Parse() int Parse() int
GetRootNode() ast.Vertex GetRootNode() ast.Vertex
GetErrors() []*errors.Error
} }
func NewParser(src []byte, v string, withTokens bool) (Parser, error) { type Config struct {
WithTokens bool
WithPositions bool
ErrorHandlerFunc func(e *errors.Error)
}
func Parse(src []byte, ver string, cfg Config) (ast.Vertex, error) {
var parser Parser var parser Parser
r, err := version.Compare(v, "7.0") r, err := version.Compare(ver, "7.0")
if err != nil { if err != nil {
return nil, err return nil, err
} }
lexer := scanner.NewLexer(src, ver, cfg.WithTokens, cfg.ErrorHandlerFunc)
if r == -1 { if r == -1 {
parser = php5.NewParser(src, v, withTokens) parser = php5.NewParser(lexer, cfg.WithTokens, cfg.ErrorHandlerFunc)
} else { } else {
parser = php7.NewParser(src, v, withTokens) parser = php7.NewParser(lexer, cfg.WithTokens, cfg.ErrorHandlerFunc)
} }
return parser, nil parser.Parse()
return parser.GetRootNode(), nil
} }

View File

@ -2,15 +2,18 @@ package printer_test
import ( import (
"bytes" "bytes"
"github.com/z7zmey/php-parser/pkg/ast"
"testing" "testing"
"github.com/z7zmey/php-parser/pkg/ast"
"github.com/z7zmey/php-parser/internal/php5" "github.com/z7zmey/php-parser/internal/php5"
"github.com/z7zmey/php-parser/internal/scanner"
"github.com/z7zmey/php-parser/pkg/printer" "github.com/z7zmey/php-parser/pkg/printer"
) )
func parsePhp5(src string) ast.Vertex { func parsePhp5(src string) ast.Vertex {
php5parser := php5.NewParser([]byte(src), "5.6", true) lexer := scanner.NewLexer([]byte(src), "5.6", true, nil)
php5parser := php5.NewParser(lexer, true, nil)
php5parser.Parse() php5parser.Parse()
return php5parser.GetRootNode() return php5parser.GetRootNode()

View File

@ -2,11 +2,13 @@ package printer_test
import ( import (
"bytes" "bytes"
"github.com/z7zmey/php-parser/pkg/ast"
"os" "os"
"testing" "testing"
"github.com/z7zmey/php-parser/pkg/ast"
"github.com/z7zmey/php-parser/internal/php7" "github.com/z7zmey/php-parser/internal/php7"
"github.com/z7zmey/php-parser/internal/scanner"
"github.com/z7zmey/php-parser/pkg/printer" "github.com/z7zmey/php-parser/pkg/printer"
) )
@ -27,7 +29,8 @@ abstract class Bar extends Baz
// parse // parse
php7parser := php7.NewParser([]byte(src), "7.4", true) lexer := scanner.NewLexer([]byte(src), "7.4", true, nil)
php7parser := php7.NewParser(lexer, true, nil)
php7parser.Parse() php7parser.Parse()
rootNode := php7parser.GetRootNode() rootNode := php7parser.GetRootNode()
@ -58,7 +61,8 @@ abstract class Bar extends Baz
} }
func parse(src string) ast.Vertex { func parse(src string) ast.Vertex {
php7parser := php7.NewParser([]byte(src), "7.4", true) lexer := scanner.NewLexer([]byte(src), "7.4", true, nil)
php7parser := php7.NewParser(lexer, true, nil)
php7parser.Parse() php7parser.Parse()
return php7parser.GetRootNode() return php7parser.GetRootNode()