refactor - ranges
This commit is contained in:
parent
1a27c52e7c
commit
446022c546
1
char.go
1
char.go
@ -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) {}
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
44
sequence.go
44
sequence.go
@ -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
|
||||||
}
|
}
|
||||||
|
13
syntax.go
13
syntax.go
@ -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)
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user