diff --git a/char.go b/char.go index 467a25c..71f30b3 100644 --- a/char.go +++ b/char.go @@ -82,10 +82,11 @@ func (p *charParser) parse(c *context) { return } - c.success(c.offset + 1) for _, includedBy := range p.includedBy { c.store.setMatch(c.offset, includedBy, c.offset+1) } + + c.success(c.offset + 1) } func (p *charParser) build(c *context) ([]*Node, bool) { diff --git a/define.go b/define.go index 12bf599..60da3b0 100644 --- a/define.go +++ b/define.go @@ -5,16 +5,8 @@ import "strconv" func dropComments(n *Node) *Node { ncc := *n nc := &ncc - - nc.Nodes = nil - for _, ni := range n.Nodes { - if ni.Name == "comment" { - continue - } - - nc.Nodes = append(nc.Nodes, dropComments(ni)) - } - + nc.Nodes = filterNodes(func(n *Node) bool { return n.Name != "comment" }, n.Nodes) + nc.Nodes = mapNodes(dropComments, nc.Nodes) return nc } @@ -60,21 +52,6 @@ func defineMember(s *Syntax, defaultName string, ct CommitType, n *Node) (string } } -func defineMembers(s *Syntax, name string, ct CommitType, n ...*Node) ([]string, error) { - var refs []string - for i, ni := range n { - nmi := childName(name, i) - ref, err := defineMember(s, nmi, ct, ni) - if err != nil { - return nil, err - } - - refs = append(refs, ref) - } - - return refs, nil -} - func defineClass(s *Syntax, name string, ct CommitType, n []*Node) error { var ( not bool @@ -184,10 +161,16 @@ func defineSequence(s *Syntax, name string, ct CommitType, n ...*Node) error { } func defineChoice(s *Syntax, name string, ct CommitType, n ...*Node) error { - nows := ct & NoWhitespace - refs, err := defineMembers(s, name, Alias|nows, n...) - if err != nil { - return err + var refs []string + memberCT := ct&NoWhitespace | Alias + for i, ni := range n { + nmi := childName(name, i) + ref, err := defineMember(s, nmi, memberCT, ni) + if err != nil { + return err + } + + refs = append(refs, ref) } return s.choice(name, ct, refs...) @@ -223,10 +206,6 @@ func defineDefinition(s *Syntax, n *Node) error { } func define(s *Syntax, n *Node) error { - if n.Name != "syntax" { - return ErrInvalidSyntax - } - n = dropComments(n) for _, ni := range n.Nodes { diff --git a/node.go b/node.go index fb1c6ee..1c49cf6 100644 --- a/node.go +++ b/node.go @@ -11,6 +11,26 @@ type Node struct { tokens []rune } +func mapNodes(m func(n *Node) *Node, n []*Node) []*Node { + var nn []*Node + for i := range n { + nn = append(nn, m(n[i])) + } + + return nn +} + +func filterNodes(f func(n *Node) bool, n []*Node) []*Node { + var nn []*Node + for i := range n { + if f(n[i]) { + nn = append(nn, n[i]) + } + } + + return nn +} + func newNode(name string, id int, from, to int, ct CommitType) *Node { return &Node{ Name: name, diff --git a/sequence.go b/sequence.go index 68e33e8..6b7bc2e 100644 --- a/sequence.go +++ b/sequence.go @@ -234,7 +234,6 @@ func (p *sequenceParser) parse(c *context) { p.items[itemIndex].parse(c) if !c.match { if currentCount < p.ranges[itemIndex][0] { - // c.store.setNoMatch(from, p.id) c.fail(from) if !p.allChars { diff --git a/syntax.go b/syntax.go index 4921744..4e6657c 100644 --- a/syntax.go +++ b/syntax.go @@ -78,6 +78,28 @@ func isValidSymbol(n string) bool { } +func (s *Syntax) applyRoot(d definition) error { + explicitRoot := d.commitType()&Root != 0 + if explicitRoot && s.explicitRoot { + return ErrMultipleRoots + } + + if s.root != nil && (explicitRoot || !s.explicitRoot) { + s.root.setCommitType(s.root.commitType() &^ Root) + } + + if explicitRoot || !s.explicitRoot { + s.root = d + s.root.setCommitType(s.root.commitType() | Root) + } + + if explicitRoot { + s.explicitRoot = true + } + + return nil +} + func (s *Syntax) register(d definition) error { if s.initialized { return ErrSyntaxInitialized @@ -87,30 +109,10 @@ func (s *Syntax) register(d definition) error { s.registry = newRegistry() } - if d.commitType()&Root != 0 { - if s.explicitRoot { - return ErrMultipleRoots - } - - if s.root != nil { - s.root.setCommitType(s.root.commitType() &^ Root) - } - - s.root = d - s.root.setCommitType(s.root.commitType() | Root) - s.explicitRoot = true - } else if !s.explicitRoot { - if s.root != nil { - s.root.setCommitType(s.root.commitType() &^ Root) - } - - s.root = d - s.root.setCommitType(s.root.commitType() | Root) + if err := s.applyRoot(d); err != nil { + return err } - // TODO: verify that definition names match the symbol criteria, or figure a better naming for the - // whitespace - return s.registry.setDefinition(d) }