refactor - ranges

This commit is contained in:
Arpad Ryszka 2017-11-04 22:49:42 +01:00
parent 1a27c52e7c
commit 446022c546
5 changed files with 38 additions and 24 deletions

View File

@ -29,6 +29,7 @@ func (p *charParser) nodeID() int { return p.id }
func (p *charParser) setID(id int) { p.id = id } func (p *charParser) setID(id int) { p.id = id }
func (p *charParser) commitType() CommitType { return Alias } func (p *charParser) commitType() CommitType { return Alias }
func (p *charParser) setCommitType(ct CommitType) {} func (p *charParser) setCommitType(ct CommitType) {}
func (p *charParser) preinit() {}
func (p *charParser) validate(*registry) error { return nil } func (p *charParser) validate(*registry) error { return nil }
func (p *charParser) init(*registry) {} func (p *charParser) init(*registry) {}

View File

@ -42,6 +42,7 @@ func (d *choiceDefinition) nodeID() int { return d.id }
func (d *choiceDefinition) setID(id int) { d.id = id } func (d *choiceDefinition) setID(id int) { d.id = id }
func (d *choiceDefinition) commitType() CommitType { return d.commit } func (d *choiceDefinition) commitType() CommitType { return d.commit }
func (d *choiceDefinition) setCommitType(ct CommitType) { d.commit = ct } func (d *choiceDefinition) setCommitType(ct CommitType) { d.commit = ct }
func (d *choiceDefinition) preinit() {}
func (d *choiceDefinition) validate(r *registry) error { func (d *choiceDefinition) validate(r *registry) error {
if d.validated { if d.validated {

View File

@ -49,6 +49,29 @@ func (d *sequenceDefinition) setID(id int) { d.id = id }
func (d *sequenceDefinition) commitType() CommitType { return d.commit } func (d *sequenceDefinition) commitType() CommitType { return d.commit }
func (d *sequenceDefinition) setCommitType(ct CommitType) { d.commit = ct } func (d *sequenceDefinition) setCommitType(ct CommitType) { d.commit = ct }
func (d *sequenceDefinition) initRanges() {
for i, item := range d.items {
if item.Min == 0 && item.Max == 0 {
item.Min, item.Max = 1, 1
} else {
if item.Min <= 0 {
item.Min = 0
}
if item.Max <= 0 {
item.Max = -1
}
}
d.items[i] = item
d.ranges = append(d.ranges, []int{item.Min, item.Max})
}
}
func (d *sequenceDefinition) preinit() {
d.initRanges()
}
func (d *sequenceDefinition) validate(r *registry) error { func (d *sequenceDefinition) validate(r *registry) error {
if d.validated { if d.validated {
return nil return nil
@ -82,18 +105,6 @@ func (d *sequenceDefinition) createBuilder() {
} }
} }
func (d *sequenceDefinition) initRanges() {
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
}
d.ranges = append(d.ranges, []int{item.Min, item.Max})
}
}
func (d *sequenceDefinition) initItems(r *registry) { func (d *sequenceDefinition) initItems(r *registry) {
allChars := true allChars := true
for _, item := range d.items { for _, item := range d.items {
@ -181,10 +192,6 @@ func (p *sequenceParser) parse(c *context) {
var parsed bool var parsed bool
for itemIndex < len(p.items) { for itemIndex < len(p.items) {
// TODO:
// - is it ok to parse before max range check? what if max=0
// - validate, normalize and document max=0
// TODO: test this f(g()) // TODO: test this f(g())
p.items[itemIndex].parse(c) p.items[itemIndex].parse(c)
if !c.matchLast { if !c.matchLast {
@ -210,8 +217,7 @@ func (p *sequenceParser) parse(c *context) {
to = c.offset to = c.offset
// TODO: max cannot be 0 if !parsed || p.ranges[itemIndex][1] > 0 && currentCount == p.ranges[itemIndex][1] {
if !parsed || p.ranges[itemIndex][1] >= 0 && currentCount == p.ranges[itemIndex][1] {
itemIndex++ itemIndex++
currentCount = 0 currentCount = 0
} }
@ -287,7 +293,7 @@ func (b *sequenceBuilder) build(c *context) ([]*Node, bool) {
nodes = append(nodes, n...) nodes = append(nodes, n...)
currentCount++ currentCount++
if b.ranges[itemIndex][1] >= 0 && currentCount == b.ranges[itemIndex][1] { if b.ranges[itemIndex][1] > 0 && currentCount == b.ranges[itemIndex][1] {
itemIndex++ itemIndex++
currentCount = 0 currentCount = 0
} }

View File

@ -18,9 +18,12 @@ const (
Root Root
) )
// if min=0&&max=0, it means min=1,max=1
// else if max<=0, it means no max
// else if min<=0, it means no min
type SequenceItem struct { type SequenceItem struct {
Name string Name string
Min, Max int // 0,0 considered as 1,1, x,0 considered as x,-1 Min, Max int
} }
type Syntax struct { type Syntax struct {
@ -40,6 +43,7 @@ type definition interface {
commitType() CommitType commitType() CommitType
setCommitType(CommitType) setCommitType(CommitType)
setID(int) setID(int)
preinit()
validate(*registry) error validate(*registry) error
init(*registry) init(*registry)
addGeneralization(int) addGeneralization(int)
@ -220,6 +224,8 @@ func (s *Syntax) CharSequence(name string, ct CommitType, chars []rune) error {
} }
func (s *Syntax) sequence(name string, ct CommitType, items ...SequenceItem) error { func (s *Syntax) sequence(name string, ct CommitType, items ...SequenceItem) error {
citems := make([]SequenceItem, len(items))
copy(citems, items)
return s.register(newSequence(name, ct, items)) return s.register(newSequence(name, ct, items))
} }
@ -251,8 +257,6 @@ func (s *Syntax) Read(r io.Reader) error {
return ErrNotImplemented return ErrNotImplemented
} }
// TODO: why normalization failed?
func (s *Syntax) Init() error { func (s *Syntax) Init() error {
if s.initFailed { if s.initFailed {
return ErrInitFailed return ErrInitFailed
@ -275,6 +279,9 @@ func (s *Syntax) Init() error {
} }
defs := s.registry.getDefinitions() defs := s.registry.getDefinitions()
for i := range defs {
defs[i].preinit()
}
if hasWhitespace(defs) { if hasWhitespace(defs) {
defs, s.root = applyWhitespace(defs) defs, s.root = applyWhitespace(defs)

View File

@ -66,8 +66,7 @@ func applyWhitespaceToSeq(s *sequenceDefinition) []definition {
whitespace := SequenceItem{Name: whitespaceName, Min: 0, Max: -1} whitespace := SequenceItem{Name: whitespaceName, Min: 0, Max: -1}
for i, item := range s.items { for i, item := range s.items {
// TODO: there should not be max=0 if item.Max == 1 {
if item.Max >= 0 && item.Max <= 1 {
if i > 0 { if i > 0 {
items = append(items, whitespace) items = append(items, whitespace)
} }