simplify build time pending check
This commit is contained in:
parent
79fa303bed
commit
1ed65518e6
3
Makefile
3
Makefile
@ -52,9 +52,10 @@ precommit: fmt build check-full
|
||||
clean:
|
||||
@rm -f *.test
|
||||
@rm -f cpu.out
|
||||
@rm -f .coverprofile
|
||||
@go clean -i ./...
|
||||
|
||||
ci-trigger: deps build check-full check-fmt
|
||||
ci-trigger: deps check-fmt build check-full
|
||||
ifeq ($(TRAVIS_BRANCH)_$(TRAVIS_PULL_REQUEST), master_false)
|
||||
make publish-coverage
|
||||
endif
|
||||
|
@ -204,11 +204,11 @@ func (b *choiceBuilder) build(c *context) ([]*Node, bool) {
|
||||
if parsed {
|
||||
c.results.dropMatchTo(c.offset, b.id, to)
|
||||
} else {
|
||||
if c.buildPending(c.offset, b.id, to) {
|
||||
if c.pending(c.offset, b.id) {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
c.markBuildPending(c.offset, b.id, to)
|
||||
c.markPending(c.offset, b.id)
|
||||
}
|
||||
|
||||
var option builder
|
||||
@ -221,7 +221,7 @@ func (b *choiceBuilder) build(c *context) ([]*Node, bool) {
|
||||
|
||||
n, _ := option.build(c)
|
||||
if !parsed {
|
||||
c.unmarkBuildPending(from, b.id, to)
|
||||
c.unmarkPending(from, b.id)
|
||||
}
|
||||
|
||||
if b.commit&Alias != 0 {
|
||||
|
100
context.go
100
context.go
@ -63,101 +63,6 @@ func (c *context) token() (rune, bool) {
|
||||
return c.tokens[c.offset], true
|
||||
}
|
||||
|
||||
func (c *context) pending(offset, id int) bool {
|
||||
if len(c.isPending) <= id {
|
||||
return false
|
||||
}
|
||||
|
||||
for i := range c.isPending[id] {
|
||||
if c.isPending[id][i] == offset {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (c *context) markPending(offset, id int) {
|
||||
if len(c.isPending) <= id {
|
||||
if cap(c.isPending) > id {
|
||||
c.isPending = c.isPending[:id+1]
|
||||
} else {
|
||||
c.isPending = c.isPending[:cap(c.isPending)]
|
||||
for i := cap(c.isPending); i <= id; i++ {
|
||||
c.isPending = append(c.isPending, nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for i := range c.isPending[id] {
|
||||
if c.isPending[id][i] == -1 {
|
||||
c.isPending[id][i] = offset
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
c.isPending[id] = append(c.isPending[id], offset)
|
||||
}
|
||||
|
||||
func (c *context) unmarkPending(offset, id int) {
|
||||
for i := range c.isPending[id] {
|
||||
if c.isPending[id][i] == offset {
|
||||
c.isPending[id][i] = -1
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *context) resetPending() {
|
||||
c.isPending = nil
|
||||
}
|
||||
|
||||
func (c *context) buildPending(offset, id, to int) bool {
|
||||
if len(c.isPending) <= id {
|
||||
return false
|
||||
}
|
||||
|
||||
for i := 0; i < len(c.isPending[id]); i += 2 {
|
||||
if c.isPending[id][i] == offset && c.isPending[id][i+1] == to {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (c *context) markBuildPending(offset, id, to int) {
|
||||
if len(c.isPending) <= id {
|
||||
if cap(c.isPending) > id {
|
||||
c.isPending = c.isPending[:id+1]
|
||||
} else {
|
||||
c.isPending = c.isPending[:cap(c.isPending)]
|
||||
for i := cap(c.isPending); i <= id; i++ {
|
||||
c.isPending = append(c.isPending, nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for i := 0; i < len(c.isPending[id]); i += 2 {
|
||||
if c.isPending[id][i] == -1 {
|
||||
c.isPending[id][i] = offset
|
||||
c.isPending[id][i+1] = to
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
c.isPending[id] = append(c.isPending[id], offset, to)
|
||||
}
|
||||
|
||||
func (c *context) unmarkBuildPending(offset, id, to int) {
|
||||
for i := 0; i < len(c.isPending[id]); i += 2 {
|
||||
if c.isPending[id][i] == offset && c.isPending[id][i+1] == to {
|
||||
c.isPending[id][i] = -1
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *context) fromResults(id int) bool {
|
||||
to, m, ok := c.results.longestResult(c.offset, id)
|
||||
if !ok {
|
||||
@ -173,6 +78,11 @@ func (c *context) fromResults(id int) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// TODO:
|
||||
// - try to move this to the parsers
|
||||
// - try to move more
|
||||
// - if doens't help performance, try move more from there to here
|
||||
|
||||
func (c *context) success(to int) {
|
||||
c.offset = to
|
||||
c.matchLast = true
|
||||
|
@ -86,11 +86,11 @@ func TestPendingWithinCap(t *testing.T) {
|
||||
|
||||
t.Run("parse", func(t *testing.T) {
|
||||
for i := 0; i < 16; i++ {
|
||||
c.markBuildPending(0, i, 0)
|
||||
c.markPending(0, i)
|
||||
}
|
||||
|
||||
for i := 0; i < 16; i++ {
|
||||
if !c.buildPending(0, i, 0) {
|
||||
if !c.pending(0, i) {
|
||||
t.Error("failed to mark build pending")
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ error reporting
|
||||
- print the line
|
||||
- print the deepest non-alias node name
|
||||
- print the documentation of the node name
|
||||
- make it work with custom tokens
|
||||
read, with error reporting
|
||||
what was the bug with the large json from eskip?
|
||||
|
||||
|
@ -5,7 +5,6 @@ type registry struct {
|
||||
ids map[string]int
|
||||
names map[int]string
|
||||
definitions map[string]definition
|
||||
parsers map[string]parser
|
||||
}
|
||||
|
||||
func newRegistry(defs ...definition) *registry {
|
||||
@ -13,7 +12,6 @@ func newRegistry(defs ...definition) *registry {
|
||||
ids: make(map[string]int),
|
||||
names: make(map[int]string),
|
||||
definitions: make(map[string]definition),
|
||||
parsers: make(map[string]parser),
|
||||
}
|
||||
|
||||
for _, def := range defs {
|
||||
|
50
results.go
50
results.go
@ -23,6 +23,7 @@ func (r *results) ensureOffset(offset int) {
|
||||
|
||||
func (r *results) setMatch(offset, id, to int) {
|
||||
r.ensureOffset(offset)
|
||||
|
||||
for i := 0; i < len(r.match[offset]); i += 2 {
|
||||
if r.match[offset][i] != id || r.match[offset][i+1] != to {
|
||||
continue
|
||||
@ -124,3 +125,52 @@ func (r *results) dropMatchTo(offset, id, to int) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *context) resetPending() {
|
||||
c.isPending = nil
|
||||
}
|
||||
|
||||
func (c *context) pending(offset, id int) bool {
|
||||
if len(c.isPending) <= id {
|
||||
return false
|
||||
}
|
||||
|
||||
for i := range c.isPending[id] {
|
||||
if c.isPending[id][i] == offset {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (c *context) markPending(offset, id int) {
|
||||
if len(c.isPending) <= id {
|
||||
if cap(c.isPending) > id {
|
||||
c.isPending = c.isPending[:id+1]
|
||||
} else {
|
||||
c.isPending = c.isPending[:cap(c.isPending)]
|
||||
for i := cap(c.isPending); i <= id; i++ {
|
||||
c.isPending = append(c.isPending, nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for i := range c.isPending[id] {
|
||||
if c.isPending[id][i] == -1 {
|
||||
c.isPending[id][i] = offset
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
c.isPending[id] = append(c.isPending[id], offset)
|
||||
}
|
||||
|
||||
func (c *context) unmarkPending(offset, id int) {
|
||||
for i := range c.isPending[id] {
|
||||
if c.isPending[id][i] == offset {
|
||||
c.isPending[id][i] = -1
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -258,11 +258,11 @@ func (b *sequenceBuilder) build(c *context) ([]*Node, bool) {
|
||||
} else if parsed {
|
||||
c.results.dropMatchTo(c.offset, b.id, to)
|
||||
} else {
|
||||
if c.buildPending(c.offset, b.id, to) {
|
||||
if c.pending(c.offset, b.id) {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
c.markBuildPending(c.offset, b.id, to)
|
||||
c.markPending(c.offset, b.id)
|
||||
}
|
||||
|
||||
var (
|
||||
@ -303,7 +303,7 @@ func (b *sequenceBuilder) build(c *context) ([]*Node, bool) {
|
||||
}
|
||||
|
||||
if !parsed {
|
||||
c.unmarkBuildPending(from, b.id, to)
|
||||
c.unmarkPending(from, b.id)
|
||||
}
|
||||
|
||||
if b.commit&Alias != 0 {
|
||||
|
Loading…
Reference in New Issue
Block a user