refactore included
This commit is contained in:
parent
507299f318
commit
72c8418e45
19
char.go
19
char.go
@ -7,7 +7,7 @@ type charParser struct {
|
||||
not bool
|
||||
chars []rune
|
||||
ranges [][]rune
|
||||
includedBy []parser
|
||||
includedBy []int
|
||||
}
|
||||
|
||||
func newChar(
|
||||
@ -30,6 +30,13 @@ func (p *charParser) nodeName() string { return p.name }
|
||||
func (p *charParser) nodeID() int { return p.id }
|
||||
func (p *charParser) setID(id int) { p.id = id }
|
||||
|
||||
func (p *charParser) init(r *registry) error { return nil }
|
||||
|
||||
func (p *charParser) setIncludedBy(r *registry, includedBy int, parsers *idSet) error {
|
||||
p.includedBy = appendIfMissing(p.includedBy, includedBy)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *charParser) parser(r *registry, parsers *idSet) (parser, error) {
|
||||
if parsers.has(p.id) {
|
||||
panic(cannotIncludeParsers(p.name))
|
||||
@ -47,14 +54,6 @@ func (p *charParser) commitType() CommitType {
|
||||
return p.commit
|
||||
}
|
||||
|
||||
func (p *charParser) setIncludedBy(includedBy parser, parsers *idSet) {
|
||||
if parsers.has(p.id) {
|
||||
panic(cannotIncludeParsers(p.name))
|
||||
}
|
||||
|
||||
p.includedBy = append(p.includedBy, includedBy)
|
||||
}
|
||||
|
||||
func (p *charParser) storeIncluded(*context, int, int) {
|
||||
panic(cannotIncludeParsers(p.name))
|
||||
}
|
||||
@ -83,6 +82,6 @@ func (p *charParser) parse(t Trace, c *context) {
|
||||
|
||||
c.success(c.offset + 1)
|
||||
for _, includedBy := range p.includedBy {
|
||||
includedBy.storeIncluded(c, c.offset, c.offset+1)
|
||||
c.store.setMatch(c.offset, includedBy, c.offset+1)
|
||||
}
|
||||
}
|
||||
|
44
choice.go
44
choice.go
@ -5,6 +5,7 @@ type choiceDefinition struct {
|
||||
id int
|
||||
commit CommitType
|
||||
elements []string
|
||||
includedBy []int
|
||||
}
|
||||
|
||||
type choiceParser struct {
|
||||
@ -12,7 +13,7 @@ type choiceParser struct {
|
||||
id int
|
||||
commit CommitType
|
||||
elements []parser
|
||||
includedBy []parser
|
||||
includedBy []int
|
||||
}
|
||||
|
||||
func newChoice(name string, ct CommitType, elements []string) *choiceDefinition {
|
||||
@ -27,6 +28,22 @@ func (d *choiceDefinition) nodeName() string { return d.name }
|
||||
func (d *choiceDefinition) nodeID() int { return d.id }
|
||||
func (d *choiceDefinition) setID(id int) { d.id = id }
|
||||
|
||||
func (d *choiceDefinition) init(r *registry) error {
|
||||
parsers := &idSet{}
|
||||
parsers.set(d.id)
|
||||
return setItemsIncludedBy(r, d.elements, d.id, parsers)
|
||||
}
|
||||
|
||||
func (d *choiceDefinition) setIncludedBy(r *registry, includedBy int, parsers *idSet) error {
|
||||
if parsers.has(d.id) {
|
||||
return nil
|
||||
}
|
||||
|
||||
d.includedBy = appendIfMissing(d.includedBy, includedBy)
|
||||
parsers.set(d.id)
|
||||
return setItemsIncludedBy(r, d.elements, includedBy, parsers)
|
||||
}
|
||||
|
||||
func (d *choiceDefinition) parser(r *registry, parsers *idSet) (parser, error) {
|
||||
p, ok := r.parser(d.name)
|
||||
if ok {
|
||||
@ -37,6 +54,7 @@ func (d *choiceDefinition) parser(r *registry, parsers *idSet) (parser, error) {
|
||||
name: d.name,
|
||||
id: d.id,
|
||||
commit: d.commit,
|
||||
includedBy: d.includedBy,
|
||||
}
|
||||
|
||||
r.setParser(cp)
|
||||
@ -48,7 +66,6 @@ func (d *choiceDefinition) parser(r *registry, parsers *idSet) (parser, error) {
|
||||
element, ok := r.parser(e)
|
||||
if ok {
|
||||
elements = append(elements, element)
|
||||
element.setIncludedBy(cp, parsers)
|
||||
continue
|
||||
}
|
||||
|
||||
@ -62,7 +79,6 @@ func (d *choiceDefinition) parser(r *registry, parsers *idSet) (parser, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
element.setIncludedBy(cp, parsers)
|
||||
elements = append(elements, element)
|
||||
}
|
||||
|
||||
@ -77,26 +93,6 @@ func (d *choiceDefinition) commitType() CommitType {
|
||||
func (p *choiceParser) nodeName() string { return p.name }
|
||||
func (p *choiceParser) nodeID() int { return p.id }
|
||||
|
||||
func (p *choiceParser) setIncludedBy(includedBy parser, parsers *idSet) {
|
||||
if parsers.has(p.id) {
|
||||
return
|
||||
}
|
||||
|
||||
p.includedBy = append(p.includedBy, includedBy)
|
||||
}
|
||||
|
||||
func (p *choiceParser) storeIncluded(c *context, from, to int) {
|
||||
if !c.excluded(from, p.id) {
|
||||
return
|
||||
}
|
||||
|
||||
c.store.setMatch(from, p.id, to)
|
||||
|
||||
for _, includedBy := range p.includedBy {
|
||||
includedBy.storeIncluded(c, from, to)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *choiceParser) parse(t Trace, c *context) {
|
||||
if p.commit&Documentation != 0 {
|
||||
c.fail(c.offset)
|
||||
@ -140,7 +136,7 @@ func (p *choiceParser) parse(t Trace, c *context) {
|
||||
|
||||
c.store.setMatch(from, p.id, to)
|
||||
for _, includedBy := range p.includedBy {
|
||||
includedBy.storeIncluded(c, from, to)
|
||||
c.store.setMatch(from, includedBy, to)
|
||||
}
|
||||
}
|
||||
|
||||
|
44
parse.go
44
parse.go
@ -6,6 +6,8 @@ type definition interface {
|
||||
nodeName() string
|
||||
nodeID() int
|
||||
setID(int)
|
||||
init(*registry) error
|
||||
setIncludedBy(*registry, int, *idSet) error
|
||||
parser(*registry, *idSet) (parser, error)
|
||||
commitType() CommitType
|
||||
// builder() builder
|
||||
@ -14,8 +16,6 @@ type definition interface {
|
||||
type parser interface {
|
||||
nodeName() string
|
||||
nodeID() int
|
||||
setIncludedBy(parser, *idSet)
|
||||
storeIncluded(*context, int, int) // can be just an id set, taking what's excluded from the context
|
||||
parse(Trace, *context)
|
||||
}
|
||||
|
||||
@ -33,6 +33,46 @@ func cannotIncludeParsers(name string) error {
|
||||
return fmt.Errorf("parser: %s cannot include other parsers", name)
|
||||
}
|
||||
|
||||
func intsContain(is []int, i int) bool {
|
||||
for _, ii := range is {
|
||||
if ii == i {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func appendIfMissing(is []int, i int) []int {
|
||||
if intsContain(is, i) {
|
||||
return is
|
||||
}
|
||||
|
||||
return append(is, i)
|
||||
}
|
||||
|
||||
func setItemsIncludedBy(r *registry, items []string, includedBy int, parsers *idSet) error {
|
||||
for _, item := range items {
|
||||
di, ok := r.definition(item)
|
||||
if !ok {
|
||||
return ErrNoParsersDefined
|
||||
}
|
||||
|
||||
di.setIncludedBy(r, includedBy, parsers)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func sequenceItemNames(items []SequenceItem) []string {
|
||||
names := make([]string, len(items))
|
||||
for i := range items {
|
||||
names[i] = items[i].Name
|
||||
}
|
||||
|
||||
return names
|
||||
}
|
||||
|
||||
func parse(t Trace, p parser, c *context) (*Node, error) {
|
||||
p.parse(t, c)
|
||||
if c.readErr != nil {
|
||||
|
67
sequence.go
67
sequence.go
@ -5,6 +5,7 @@ type sequenceDefinition struct {
|
||||
id int
|
||||
commit CommitType
|
||||
items []SequenceItem
|
||||
includedBy []int
|
||||
}
|
||||
|
||||
type sequenceParser struct {
|
||||
@ -13,7 +14,7 @@ type sequenceParser struct {
|
||||
commit CommitType
|
||||
items []parser
|
||||
ranges [][]int
|
||||
includedBy []parser
|
||||
includedBy []int
|
||||
}
|
||||
|
||||
func newSequence(name string, ct CommitType, items []SequenceItem) *sequenceDefinition {
|
||||
@ -28,6 +29,42 @@ func (d *sequenceDefinition) nodeName() string { return d.name }
|
||||
func (d *sequenceDefinition) nodeID() int { return d.id }
|
||||
func (d *sequenceDefinition) setID(id int) { d.id = id }
|
||||
|
||||
func (d *sequenceDefinition) includeItems() bool {
|
||||
return len(d.items) == 1 && d.items[0].Min == 1 && d.items[0].Max == 1
|
||||
}
|
||||
|
||||
func (d *sequenceDefinition) init(r *registry) error {
|
||||
for _, item := range d.items {
|
||||
if item.Min == 0 && item.Max == 0 {
|
||||
item.Min, item.Max = 1, 1
|
||||
} else if item.Max == 0 {
|
||||
item.Max = -1
|
||||
}
|
||||
}
|
||||
|
||||
if !d.includeItems() {
|
||||
return nil
|
||||
}
|
||||
|
||||
parsers := &idSet{}
|
||||
parsers.set(d.id)
|
||||
return setItemsIncludedBy(r, sequenceItemNames(d.items), d.id, parsers)
|
||||
}
|
||||
|
||||
func (d *sequenceDefinition) setIncludedBy(r *registry, includedBy int, parsers *idSet) error {
|
||||
if parsers.has(d.id) {
|
||||
return nil
|
||||
}
|
||||
|
||||
d.includedBy = appendIfMissing(d.includedBy, includedBy)
|
||||
if !d.includeItems() {
|
||||
return nil
|
||||
}
|
||||
|
||||
parsers.set(d.id)
|
||||
return setItemsIncludedBy(r, sequenceItemNames(d.items), includedBy, parsers)
|
||||
}
|
||||
|
||||
func (d *sequenceDefinition) parser(r *registry, parsers *idSet) (parser, error) {
|
||||
if parsers.has(d.id) {
|
||||
panic(cannotIncludeParsers(d.name))
|
||||
@ -42,6 +79,7 @@ func (d *sequenceDefinition) parser(r *registry, parsers *idSet) (parser, error)
|
||||
name: d.name,
|
||||
id: d.id,
|
||||
commit: d.commit,
|
||||
includedBy: d.includedBy,
|
||||
}
|
||||
|
||||
r.setParser(sp)
|
||||
@ -81,11 +119,6 @@ func (d *sequenceDefinition) parser(r *registry, parsers *idSet) (parser, error)
|
||||
ranges = append(ranges, []int{item.Min, item.Max})
|
||||
}
|
||||
|
||||
// for single items, acts like a choice
|
||||
if len(items) == 1 && ranges[0][0] == 1 && ranges[0][1] == 1 {
|
||||
items[0].setIncludedBy(sp, parsers)
|
||||
}
|
||||
|
||||
sp.items = items
|
||||
sp.ranges = ranges
|
||||
return sp, nil
|
||||
@ -98,26 +131,6 @@ func (d *sequenceDefinition) commitType() CommitType {
|
||||
func (p *sequenceParser) nodeName() string { return p.name }
|
||||
func (p *sequenceParser) nodeID() int { return p.id }
|
||||
|
||||
func (p *sequenceParser) setIncludedBy(includedBy parser, parsers *idSet) {
|
||||
if parsers.has(p.id) {
|
||||
return
|
||||
}
|
||||
|
||||
p.includedBy = append(p.includedBy, includedBy)
|
||||
}
|
||||
|
||||
func (p *sequenceParser) storeIncluded(c *context, from, to int) {
|
||||
if !c.excluded(from, p.id) {
|
||||
return
|
||||
}
|
||||
|
||||
c.store.setMatch(from, p.id, to)
|
||||
|
||||
for _, includedBy := range p.includedBy {
|
||||
includedBy.storeIncluded(c, from, to)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *sequenceParser) parse(t Trace, c *context) {
|
||||
if p.commit&Documentation != 0 {
|
||||
c.fail(c.offset)
|
||||
@ -169,7 +182,7 @@ func (p *sequenceParser) parse(t Trace, c *context) {
|
||||
}
|
||||
|
||||
for _, includedBy := range p.includedBy {
|
||||
includedBy.storeIncluded(c, from, to)
|
||||
c.store.setMatch(from, includedBy, to)
|
||||
}
|
||||
|
||||
c.store.setMatch(from, p.id, to)
|
||||
|
Loading…
Reference in New Issue
Block a user