Skip to content

Commit

Permalink
Keep the order of AST nodes constant
Browse files Browse the repository at this point in the history
  • Loading branch information
nihei9 committed Sep 22, 2021
1 parent 7be1d27 commit cf4f533
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 20 deletions.
13 changes: 12 additions & 1 deletion compiler/compiler.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,8 +201,19 @@ func compile(entries []*spec.LexEntry, modeName2ID map[spec.LexModeName]spec.Lex
var root astNode
var symTab *symbolTable
{
pats := make([]*patternEntry, len(patterns)+1)
pats[spec.LexModeKindIDNil] = &patternEntry{
id: spec.LexModeKindIDNil,
}
for id, pattern := range patterns {
pats[id] = &patternEntry{
id: id,
pattern: pattern,
}
}

var err error
root, symTab, err = parse(patterns, fragmentPatterns)
root, symTab, err = parse(pats, fragmentPatterns)
if err != nil {
return nil, err
}
Expand Down
7 changes: 5 additions & 2 deletions compiler/dfa_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@ import (
)

func TestGenDFA(t *testing.T) {
root, symTab, err := parse(map[spec.LexModeKindID][]byte{
1: []byte("(a|b)*abb"),
root, symTab, err := parse([]*patternEntry{
{
id: spec.LexModeKindIDMin,
pattern: []byte("(a|b)*abb"),
},
}, nil)
if err != nil {
t.Fatal(err)
Expand Down
36 changes: 23 additions & 13 deletions compiler/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,13 @@ func genSymTab(symTab *symbolTable, node astNode) *symbolTable {
return symTab
}

func parse(regexps map[spec.LexModeKindID][]byte, fragments map[string][]byte) (astNode, *symbolTable, error) {
if len(regexps) == 0 {
type patternEntry struct {
id spec.LexModeKindID
pattern []byte
}

func parse(pats []*patternEntry, fragments map[string][]byte) (astNode, *symbolTable, error) {
if len(pats) == 0 {
return nil, nil, fmt.Errorf("parse() needs at least one token entry")
}

Expand All @@ -91,7 +96,7 @@ func parse(regexps map[spec.LexModeKindID][]byte, fragments map[string][]byte) (
fragmentASTs = map[string]astNode{}
}

root, err := parseRegexp(regexps, fragmentASTs)
root, err := parseRegexp(pats, fragmentASTs)
if err != nil {
return nil, nil, err
}
Expand Down Expand Up @@ -161,17 +166,22 @@ func parseFragments(fragments map[string][]byte) (map[string]astNode, error) {
return fragmentASTs, nil
}

func parseRegexp(regexps map[spec.LexModeKindID][]byte, fragmentASTs map[string]astNode) (astNode, error) {
func parseRegexp(pats []*patternEntry, fragmentASTs map[string]astNode) (astNode, error) {
symPos := symbolPositionMin
var root astNode
var perrs []*ParseError
for id, pattern := range regexps {
p := newParser(bytes.NewReader(pattern))

for _, pat := range pats {
if pat.id == spec.LexModeKindIDNil {
continue
}

p := newParser(bytes.NewReader(pat.pattern))
ast, err := p.parse()
if err != nil {
perrs = append(perrs, &ParseError{
ID: id,
Pattern: pattern,
ID: pat.id,
Pattern: pat.pattern,
Cause: err,
Details: p.errMsgDetails,
})
Expand All @@ -180,18 +190,18 @@ func parseRegexp(regexps map[spec.LexModeKindID][]byte, fragmentASTs map[string]
remains := applyFragments(ast, fragmentASTs)
if len(remains) > 0 {
perrs = append(perrs, &ParseError{
ID: id,
Pattern: pattern,
ID: pat.id,
Pattern: pat.pattern,
Cause: fmt.Errorf("undefined fragment: %+v", remains),
})
continue
}
ast = newConcatNode(ast, newEndMarkerNode(id))
ast = newConcatNode(ast, newEndMarkerNode(pat.id))
symPos, err = positionSymbols(ast, symPos)
if err != nil {
perrs = append(perrs, &ParseError{
ID: id,
Pattern: pattern,
ID: pat.id,
Pattern: pat.pattern,
Cause: err,
Details: p.errMsgDetails,
})
Expand Down
14 changes: 10 additions & 4 deletions compiler/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1199,8 +1199,11 @@ func TestParse(t *testing.T) {
for kind, pattern := range tt.fragments {
fragments[kind] = []byte(pattern)
}
ast, _, err := parse(map[spec.LexModeKindID][]byte{
1: []byte(tt.pattern),
ast, _, err := parse([]*patternEntry{
{
id: spec.LexModeKindIDMin,
pattern: []byte(tt.pattern),
},
}, fragments)
if tt.syntaxError != nil {
// printAST(os.Stdout, ast, "", "", false)
Expand Down Expand Up @@ -1239,8 +1242,11 @@ func TestParse(t *testing.T) {
}

func TestParse_FollowAndSymbolTable(t *testing.T) {
root, symTab, err := parse(map[spec.LexModeKindID][]byte{
1: []byte("(a|b)*abb"),
root, symTab, err := parse([]*patternEntry{
{
id: spec.LexModeKindIDMin,
pattern: []byte("(a|b)*abb"),
},
}, nil)
if err != nil {
t.Fatal(err)
Expand Down

0 comments on commit cf4f533

Please sign in to comment.