use generated syntax for all parsers
This commit is contained in:
parent
070ddcf77f
commit
68ce88cc6f
41
Makefile
41
Makefile
@ -8,10 +8,35 @@ deps:
|
|||||||
go get -t ./...
|
go get -t ./...
|
||||||
|
|
||||||
imports: $(SOURCES)
|
imports: $(SOURCES)
|
||||||
|
@echo imports
|
||||||
@goimports -w $(SOURCES)
|
@goimports -w $(SOURCES)
|
||||||
|
|
||||||
build: $(SOURCES)
|
build: $(SOURCES)
|
||||||
go build ./...
|
go build
|
||||||
|
|
||||||
|
head: $(SOURCES)
|
||||||
|
go run scripts/createhead.go -- \
|
||||||
|
char.go \
|
||||||
|
sequence.go \
|
||||||
|
choice.go \
|
||||||
|
idset.go \
|
||||||
|
results.go \
|
||||||
|
context.go \
|
||||||
|
nodehead.go \
|
||||||
|
syntaxhead.go \
|
||||||
|
> head.go
|
||||||
|
|
||||||
|
generate: $(SOURCES) $(PARSERS) head
|
||||||
|
go run scripts/boot.go < syntax.treerack > self/self.go.next
|
||||||
|
@mv self/self.go{.next,}
|
||||||
|
@gofmt -s -w self/self.go
|
||||||
|
|
||||||
|
regenerate: $(SOURCES) $(PARSERS) head
|
||||||
|
go run scripts/boot.go < syntax.treerack > self/self.go.next
|
||||||
|
@mv self/self.go{.next,}
|
||||||
|
go run scripts/boot.go < syntax.treerack > self/self.go.next
|
||||||
|
@mv self/self.go{.next,}
|
||||||
|
@gofmt -s -w self/self.go
|
||||||
|
|
||||||
check: imports build $(PARSERS)
|
check: imports build $(PARSERS)
|
||||||
go test -test.short -run ^Test
|
go test -test.short -run ^Test
|
||||||
@ -39,21 +64,23 @@ cpu: cpu.out
|
|||||||
go tool pprof -top cpu.out
|
go tool pprof -top cpu.out
|
||||||
|
|
||||||
fmt: $(SOURCES)
|
fmt: $(SOURCES)
|
||||||
|
@echo fmt
|
||||||
@gofmt -w -s $(SOURCES)
|
@gofmt -w -s $(SOURCES)
|
||||||
|
|
||||||
check-fmt: $(SOURCES)
|
check-fmt: $(SOURCES)
|
||||||
|
@echo check fmt
|
||||||
@if [ "$$(gofmt -s -d $(SOURCES))" != "" ]; then false; else true; fi
|
@if [ "$$(gofmt -s -d $(SOURCES))" != "" ]; then false; else true; fi
|
||||||
|
|
||||||
vet:
|
vet:
|
||||||
@go vet
|
go vet
|
||||||
|
|
||||||
precommit: fmt vet build check-full
|
precommit: regenerate fmt vet build check-full
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
@rm -f *.test
|
rm -f *.test
|
||||||
@rm -f cpu.out
|
rm -f cpu.out
|
||||||
@rm -f .coverprofile
|
rm -f .coverprofile
|
||||||
@go clean -i ./...
|
go clean -i ./...
|
||||||
|
|
||||||
ci-trigger: deps check-fmt build check-full
|
ci-trigger: deps check-fmt build check-full
|
||||||
ifeq ($(TRAVIS_BRANCH)_$(TRAVIS_PULL_REQUEST), master_false)
|
ifeq ($(TRAVIS_BRANCH)_$(TRAVIS_PULL_REQUEST), master_false)
|
||||||
|
6
boot.go
6
boot.go
@ -5,10 +5,6 @@ import "os"
|
|||||||
func bootSyntax() (*Syntax, error) {
|
func bootSyntax() (*Syntax, error) {
|
||||||
f, _ := os.Open("syntax.treerack")
|
f, _ := os.Open("syntax.treerack")
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
|
|
||||||
// never fails:
|
|
||||||
doc, _ := parsegen(f)
|
|
||||||
|
|
||||||
s := &Syntax{}
|
s := &Syntax{}
|
||||||
return s, define(s, doc)
|
return s, s.ReadSyntax(f)
|
||||||
}
|
}
|
||||||
|
284
bootsyntax.go
284
bootsyntax.go
@ -1,284 +0,0 @@
|
|||||||
package treerack
|
|
||||||
|
|
||||||
var bootSyntaxDefs = [][]string{{
|
|
||||||
"chars", "space", "alias", " ",
|
|
||||||
}, {
|
|
||||||
"chars", "tab", "alias", "\\t",
|
|
||||||
}, {
|
|
||||||
"chars", "nl", "alias", "\\n",
|
|
||||||
}, {
|
|
||||||
"chars", "backspace", "alias", "\\b",
|
|
||||||
}, {
|
|
||||||
"chars", "formfeed", "alias", "\\f",
|
|
||||||
}, {
|
|
||||||
"chars", "carryreturn", "alias", "\\r",
|
|
||||||
}, {
|
|
||||||
"chars", "verticaltab", "alias", "\\v",
|
|
||||||
}, {
|
|
||||||
"choice",
|
|
||||||
"wschar",
|
|
||||||
"alias",
|
|
||||||
"space",
|
|
||||||
"tab",
|
|
||||||
"nl",
|
|
||||||
"backspace",
|
|
||||||
"formfeed",
|
|
||||||
"carryreturn",
|
|
||||||
"verticaltab",
|
|
||||||
}, {
|
|
||||||
"chars", "open-block-comment", "alias", "/*",
|
|
||||||
}, {
|
|
||||||
"chars", "close-block-comment", "alias", "*/",
|
|
||||||
}, {
|
|
||||||
"chars", "star", "alias", "*",
|
|
||||||
}, {
|
|
||||||
"class", "not-slash", "alias", "^/",
|
|
||||||
}, {
|
|
||||||
"class", "not-star", "alias", "^*",
|
|
||||||
}, {
|
|
||||||
"chars", "double-slash", "alias", "//",
|
|
||||||
}, {
|
|
||||||
"class", "not-nl", "alias", "^\\n",
|
|
||||||
}, {
|
|
||||||
"sequence", "not-block-close", "alias", "star", "not-slash",
|
|
||||||
}, {
|
|
||||||
"choice", "block-comment-char", "alias", "not-block-close", "not-star",
|
|
||||||
}, {
|
|
||||||
"sequence", "block-comment-body", "alias", "block-comment-char:0:-1",
|
|
||||||
}, {
|
|
||||||
"sequence",
|
|
||||||
"block-comment",
|
|
||||||
"alias",
|
|
||||||
"open-block-comment",
|
|
||||||
"block-comment-body",
|
|
||||||
"close-block-comment",
|
|
||||||
}, {
|
|
||||||
"sequence", "not-nls", "alias", "not-nl:0:-1",
|
|
||||||
}, {
|
|
||||||
"sequence", "line-comment", "alias", "double-slash", "not-nls",
|
|
||||||
}, {
|
|
||||||
"choice", "comment-segment", "alias", "block-comment", "line-comment",
|
|
||||||
}, {
|
|
||||||
"sequence", "wss", "alias", "wschar:0:-1",
|
|
||||||
}, {
|
|
||||||
"sequence", "optional-nl", "alias", "nl:0:1",
|
|
||||||
}, {
|
|
||||||
"choice",
|
|
||||||
"ws-no-nl",
|
|
||||||
"alias",
|
|
||||||
"space",
|
|
||||||
"tab",
|
|
||||||
"backspace",
|
|
||||||
"formfeed",
|
|
||||||
"carryreturn",
|
|
||||||
"verticaltab",
|
|
||||||
}, {
|
|
||||||
"sequence",
|
|
||||||
"continue-comment-segment",
|
|
||||||
"alias",
|
|
||||||
"ws-no-nl",
|
|
||||||
"optional-nl",
|
|
||||||
"ws-no-nl",
|
|
||||||
"comment-segment",
|
|
||||||
}, {
|
|
||||||
"sequence", "continue-comment", "alias", "continue-comment-segment:0:-1",
|
|
||||||
}, {
|
|
||||||
"sequence",
|
|
||||||
"comment",
|
|
||||||
"none",
|
|
||||||
"comment-segment",
|
|
||||||
"continue-comment",
|
|
||||||
}, {
|
|
||||||
"choice", "wsc", "alias", "wschar", "comment",
|
|
||||||
}, {
|
|
||||||
"sequence", "wscs", "alias", "wsc:0:-1",
|
|
||||||
}, {
|
|
||||||
"anything", "anything", "alias",
|
|
||||||
}, {
|
|
||||||
"chars", "any-char", "none", ".",
|
|
||||||
}, {
|
|
||||||
"chars", "open-square", "alias", "[",
|
|
||||||
}, {
|
|
||||||
"chars", "close-square", "alias", "]",
|
|
||||||
}, {
|
|
||||||
"chars", "class-not", "none", "^",
|
|
||||||
}, {
|
|
||||||
"chars", "dash", "alias", "-",
|
|
||||||
}, {
|
|
||||||
"sequence", "optional-class-not", "alias", "class-not:0:1",
|
|
||||||
}, {
|
|
||||||
"class", "not-class-control", "alias", "^\\\\\\[\\]\\^\\-",
|
|
||||||
}, {
|
|
||||||
"chars", "escape", "alias", "\\\\",
|
|
||||||
}, {
|
|
||||||
"sequence", "escaped-char", "alias", "escape", "anything",
|
|
||||||
}, {
|
|
||||||
"choice", "class-char", "none", "not-class-control", "escaped-char",
|
|
||||||
}, {
|
|
||||||
"sequence", "char-range", "none", "class-char", "dash", "class-char",
|
|
||||||
}, {
|
|
||||||
"choice", "char-or-range", "alias", "class-char", "char-range",
|
|
||||||
}, {
|
|
||||||
"sequence", "chars-or-ranges", "alias", "char-or-range:0:-1",
|
|
||||||
}, {
|
|
||||||
"sequence", "char-class", "none", "open-square", "optional-class-not", "chars-or-ranges", "close-square",
|
|
||||||
}, {
|
|
||||||
"chars", "double-quote", "alias", "\\\"",
|
|
||||||
}, {
|
|
||||||
"class", "not-char-sequence-control", "alias", "^\\\\\"",
|
|
||||||
}, {
|
|
||||||
"choice", "sequence-char", "none", "not-char-sequence-control", "escaped-char",
|
|
||||||
}, {
|
|
||||||
"sequence", "char-sequence-chars", "alias", "sequence-char:0:-1",
|
|
||||||
}, {
|
|
||||||
"sequence", "char-sequence", "none", "double-quote", "char-sequence-chars", "double-quote",
|
|
||||||
}, {
|
|
||||||
"choice", "terminal", "alias", "any-char", "char-class", "char-sequence",
|
|
||||||
}, {
|
|
||||||
"class", "symbol-char", "alias", symbolChars,
|
|
||||||
}, {
|
|
||||||
"sequence", "symbol-chars", "alias", "symbol-char:1:-1",
|
|
||||||
}, {
|
|
||||||
"sequence", "symbol", "none", "symbol-chars",
|
|
||||||
}, {
|
|
||||||
"chars", "open-paren", "alias", "(",
|
|
||||||
}, {
|
|
||||||
"chars", "close-paren", "alias", ")",
|
|
||||||
}, {
|
|
||||||
"sequence", "group", "alias", "open-paren", "wscs", "expression", "wscs", "close-paren",
|
|
||||||
}, {
|
|
||||||
"chars", "open-brace", "alias", "{",
|
|
||||||
}, {
|
|
||||||
"chars", "close-brace", "alias", "}",
|
|
||||||
}, {
|
|
||||||
"class", "digit", "alias", "0-9",
|
|
||||||
}, {
|
|
||||||
"sequence", "number", "alias", "digit:1:-1",
|
|
||||||
}, {
|
|
||||||
"sequence", "count", "none", "number",
|
|
||||||
}, {
|
|
||||||
"sequence", "count-quantifier", "none", "open-brace", "wscs", "count", "wscs", "close-brace",
|
|
||||||
}, {
|
|
||||||
"sequence", "range-from", "none", "number",
|
|
||||||
}, {
|
|
||||||
"sequence", "range-to", "none", "number",
|
|
||||||
}, {
|
|
||||||
"chars", "comma", "alias", ",",
|
|
||||||
}, {
|
|
||||||
"sequence",
|
|
||||||
"range-quantifier",
|
|
||||||
"none",
|
|
||||||
"open-brace",
|
|
||||||
"wscs",
|
|
||||||
"range-from",
|
|
||||||
"wscs",
|
|
||||||
"comma",
|
|
||||||
"wscs",
|
|
||||||
"range-to",
|
|
||||||
"close-brace",
|
|
||||||
}, {
|
|
||||||
"chars", "one-or-more", "none", "+",
|
|
||||||
}, {
|
|
||||||
"chars", "zero-or-more", "none", "*",
|
|
||||||
}, {
|
|
||||||
"chars", "zero-or-one", "none", "?",
|
|
||||||
}, {
|
|
||||||
"choice",
|
|
||||||
"quantity",
|
|
||||||
"alias",
|
|
||||||
"count-quantifier",
|
|
||||||
"range-quantifier",
|
|
||||||
"one-or-more",
|
|
||||||
"zero-or-more",
|
|
||||||
"zero-or-one",
|
|
||||||
}, {
|
|
||||||
"choice", "quantifiable", "alias", "terminal", "symbol", "group",
|
|
||||||
}, {
|
|
||||||
"choice", "item-choice", "alias", "terminal", "symbol", "group",
|
|
||||||
}, {
|
|
||||||
"sequence", "item", "none", "item-choice", "quantity:0:1",
|
|
||||||
}, {
|
|
||||||
"sequence", "item-continue", "alias", "wscs", "item",
|
|
||||||
}, {
|
|
||||||
"sequence", "items-continue", "alias", "item-continue:0:-1",
|
|
||||||
}, {
|
|
||||||
"sequence", "sequence", "none", "item", "items-continue",
|
|
||||||
}, {
|
|
||||||
"choice", "option", "alias", "terminal", "symbol", "group", "sequence",
|
|
||||||
}, {
|
|
||||||
"chars", "pipe", "alias", "|",
|
|
||||||
}, {
|
|
||||||
"sequence", "option-continue", "alias", "wscs", "pipe", "wscs", "option",
|
|
||||||
}, {
|
|
||||||
"sequence", "options-continue", "alias", "option-continue:1:-1",
|
|
||||||
}, {
|
|
||||||
"sequence", "choice", "none", "option", "options-continue",
|
|
||||||
}, {
|
|
||||||
"choice",
|
|
||||||
"expression",
|
|
||||||
"alias",
|
|
||||||
"terminal",
|
|
||||||
"symbol",
|
|
||||||
"group",
|
|
||||||
"sequence",
|
|
||||||
"choice",
|
|
||||||
}, {
|
|
||||||
"chars", "alias", "none", "alias",
|
|
||||||
}, {
|
|
||||||
"chars", "ws", "none", "ws",
|
|
||||||
}, {
|
|
||||||
"chars", "nows", "none", "nows",
|
|
||||||
}, {
|
|
||||||
"chars", "failpass", "none", "failpass",
|
|
||||||
}, {
|
|
||||||
"chars", "root", "none", "root",
|
|
||||||
}, {
|
|
||||||
"choice", "flag", "alias", "alias", "ws", "nows", "failpass", "root",
|
|
||||||
}, {
|
|
||||||
"chars", "colon", "alias", ":",
|
|
||||||
}, {
|
|
||||||
"sequence", "flag-tag", "alias", "colon", "flag",
|
|
||||||
}, {
|
|
||||||
"sequence", "flags", "alias", "flag-tag:0:-1",
|
|
||||||
}, {
|
|
||||||
"chars", "equal", "alias", "=",
|
|
||||||
}, {
|
|
||||||
"sequence", "definition", "none", "symbol", "flags", "wscs", "equal", "wscs", "expression",
|
|
||||||
}, {
|
|
||||||
"chars", "semicolon", "alias", ";",
|
|
||||||
}, {
|
|
||||||
"choice", "wsc-or-semicolon", "alias", "wsc", "semicolon",
|
|
||||||
}, {
|
|
||||||
"sequence", "wsc-or-semicolons", "alias", "wsc-or-semicolon:0:-1",
|
|
||||||
}, {
|
|
||||||
"sequence",
|
|
||||||
"subsequent-definition",
|
|
||||||
"alias",
|
|
||||||
"wscs",
|
|
||||||
"semicolon",
|
|
||||||
"wsc-or-semicolons",
|
|
||||||
"definition",
|
|
||||||
}, {
|
|
||||||
"sequence",
|
|
||||||
"subsequent-definitions",
|
|
||||||
"alias",
|
|
||||||
"subsequent-definition:0:-1",
|
|
||||||
}, {
|
|
||||||
"sequence",
|
|
||||||
"definitions",
|
|
||||||
"alias",
|
|
||||||
"definition",
|
|
||||||
"subsequent-definitions",
|
|
||||||
}, {
|
|
||||||
"sequence",
|
|
||||||
"opt-definitions",
|
|
||||||
"alias",
|
|
||||||
"definitions:0:1",
|
|
||||||
}, {
|
|
||||||
"sequence",
|
|
||||||
"syntax",
|
|
||||||
"root",
|
|
||||||
"wsc-or-semicolons",
|
|
||||||
"opt-definitions",
|
|
||||||
"wsc-or-semicolons",
|
|
||||||
}}
|
|
116
char.go
116
char.go
@ -1,15 +1,5 @@
|
|||||||
package treerack
|
package treerack
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
charClassEscape = '\\'
|
|
||||||
charClassBanned = "\\[]^-\b\f\n\r\t\v"
|
|
||||||
)
|
|
||||||
|
|
||||||
type charParser struct {
|
type charParser struct {
|
||||||
name string
|
name string
|
||||||
id int
|
id int
|
||||||
@ -23,70 +13,9 @@ type charBuilder struct {
|
|||||||
id int
|
id int
|
||||||
}
|
}
|
||||||
|
|
||||||
func newChar(
|
|
||||||
name string,
|
|
||||||
not bool,
|
|
||||||
chars []rune,
|
|
||||||
ranges [][]rune,
|
|
||||||
) *charParser {
|
|
||||||
return &charParser{
|
|
||||||
name: name,
|
|
||||||
not: not,
|
|
||||||
chars: chars,
|
|
||||||
ranges: ranges,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *charParser) nodeName() string { return p.name }
|
func (p *charParser) nodeName() string { return p.name }
|
||||||
func (p *charParser) setName(n string) { p.name = n }
|
|
||||||
func (p *charParser) nodeID() int { return p.id }
|
func (p *charParser) nodeID() int { return p.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) preinit() {}
|
|
||||||
func (p *charParser) validate(*registry) error { return nil }
|
|
||||||
func (p *charParser) init(*registry) {}
|
|
||||||
func (p *charParser) addGeneralization(int) {}
|
|
||||||
func (p *charParser) parser() parser { return p }
|
|
||||||
|
|
||||||
func (p *charParser) builder() builder {
|
|
||||||
return &charBuilder{
|
|
||||||
id: p.id,
|
|
||||||
name: p.name,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *charParser) isSingleChar() bool {
|
|
||||||
return !p.not && len(p.chars) == 1 && len(p.ranges) == 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *charParser) format(_ *registry, f formatFlags) string {
|
|
||||||
if p.not && len(p.chars) == 0 && len(p.ranges) == 0 {
|
|
||||||
return "."
|
|
||||||
}
|
|
||||||
|
|
||||||
esc := func(c ...rune) []rune {
|
|
||||||
return escape(charClassEscape, []rune(charClassBanned), c)
|
|
||||||
}
|
|
||||||
|
|
||||||
var s []rune
|
|
||||||
s = append(s, '[')
|
|
||||||
|
|
||||||
if p.not {
|
|
||||||
s = append(s, '^')
|
|
||||||
}
|
|
||||||
|
|
||||||
s = append(s, esc(p.chars...)...)
|
|
||||||
|
|
||||||
for i := range p.ranges {
|
|
||||||
s = append(s, esc(p.ranges[i][0])...)
|
|
||||||
s = append(s, '-')
|
|
||||||
s = append(s, esc(p.ranges[i][1])...)
|
|
||||||
}
|
|
||||||
|
|
||||||
s = append(s, ']')
|
|
||||||
return string(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
func matchChar(chars []rune, ranges [][]rune, not bool, char rune) bool {
|
func matchChar(chars []rune, ranges [][]rune, not bool, char rune) bool {
|
||||||
for _, ci := range chars {
|
for _, ci := range chars {
|
||||||
@ -122,54 +51,9 @@ func (p *charParser) parse(c *context) {
|
|||||||
c.success(c.offset + 1)
|
c.success(c.offset + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *charParser) generate(w io.Writer, done map[string]bool) error {
|
|
||||||
if done[p.name] {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
done[p.name] = true
|
|
||||||
|
|
||||||
var err error
|
|
||||||
fprintf := func(f string, args ...interface{}) {
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = fmt.Fprintf(w, f, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf("var p%d = charParser{", p.id)
|
|
||||||
fprintf("id: %d, not: %t,", p.id, p.not)
|
|
||||||
|
|
||||||
fprintf("chars: []rune{")
|
|
||||||
for i := range p.chars {
|
|
||||||
fprintf("%d,", p.chars[i])
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf("},")
|
|
||||||
|
|
||||||
fprintf("ranges: [][]rune{")
|
|
||||||
for i := range p.ranges {
|
|
||||||
fprintf("{%d, %d},", p.ranges[i][0], p.ranges[i][1])
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf("}};")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *charBuilder) nodeName() string { return b.name }
|
func (b *charBuilder) nodeName() string { return b.name }
|
||||||
func (b *charBuilder) nodeID() int { return b.id }
|
func (b *charBuilder) nodeID() int { return b.id }
|
||||||
|
|
||||||
func (b *charBuilder) build(c *context) ([]*Node, bool) {
|
func (b *charBuilder) build(c *context) ([]*Node, bool) {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *charBuilder) generate(w io.Writer, done map[string]bool) error {
|
|
||||||
if done[b.name] {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
done[b.name] = true
|
|
||||||
_, err := fmt.Fprintf(w, "var b%d = charBuilder{};", b.id)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
118
chardefine.go
Normal file
118
chardefine.go
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
package treerack
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
charClassEscape = '\\'
|
||||||
|
charClassBanned = "\\[]^-\b\f\n\r\t\v"
|
||||||
|
)
|
||||||
|
|
||||||
|
func newChar(
|
||||||
|
name string,
|
||||||
|
not bool,
|
||||||
|
chars []rune,
|
||||||
|
ranges [][]rune,
|
||||||
|
) *charParser {
|
||||||
|
return &charParser{
|
||||||
|
name: name,
|
||||||
|
not: not,
|
||||||
|
chars: chars,
|
||||||
|
ranges: ranges,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *charParser) setName(n string) { p.name = n }
|
||||||
|
func (p *charParser) setID(id int) { p.id = id }
|
||||||
|
func (p *charParser) setCommitType(ct CommitType) {}
|
||||||
|
func (p *charParser) preinit() {}
|
||||||
|
func (p *charParser) validate(*registry) error { return nil }
|
||||||
|
func (p *charParser) init(*registry) {}
|
||||||
|
func (p *charParser) addGeneralization(int) {}
|
||||||
|
func (p *charParser) parser() parser { return p }
|
||||||
|
|
||||||
|
func (p *charParser) builder() builder {
|
||||||
|
return &charBuilder{
|
||||||
|
id: p.id,
|
||||||
|
name: p.name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *charParser) isSingleChar() bool {
|
||||||
|
return !p.not && len(p.chars) == 1 && len(p.ranges) == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *charParser) format(_ *registry, f formatFlags) string {
|
||||||
|
if p.not && len(p.chars) == 0 && len(p.ranges) == 0 {
|
||||||
|
return "."
|
||||||
|
}
|
||||||
|
|
||||||
|
esc := func(c ...rune) []rune {
|
||||||
|
return escape(charClassEscape, []rune(charClassBanned), c)
|
||||||
|
}
|
||||||
|
|
||||||
|
var s []rune
|
||||||
|
s = append(s, '[')
|
||||||
|
|
||||||
|
if p.not {
|
||||||
|
s = append(s, '^')
|
||||||
|
}
|
||||||
|
|
||||||
|
s = append(s, esc(p.chars...)...)
|
||||||
|
|
||||||
|
for i := range p.ranges {
|
||||||
|
s = append(s, esc(p.ranges[i][0])...)
|
||||||
|
s = append(s, '-')
|
||||||
|
s = append(s, esc(p.ranges[i][1])...)
|
||||||
|
}
|
||||||
|
|
||||||
|
s = append(s, ']')
|
||||||
|
return string(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *charParser) generate(w io.Writer, done map[string]bool) error {
|
||||||
|
if done[p.name] {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
done[p.name] = true
|
||||||
|
|
||||||
|
var err error
|
||||||
|
fprintf := func(f string, args ...interface{}) {
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = fmt.Fprintf(w, f, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf("var p%d = charParser{", p.id)
|
||||||
|
fprintf("id: %d, not: %t,", p.id, p.not)
|
||||||
|
|
||||||
|
fprintf("chars: []rune{")
|
||||||
|
for i := range p.chars {
|
||||||
|
fprintf("%d,", p.chars[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf("},")
|
||||||
|
|
||||||
|
fprintf("ranges: [][]rune{")
|
||||||
|
for i := range p.ranges {
|
||||||
|
fprintf("{%d, %d},", p.ranges[i][0], p.ranges[i][1])
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf("}};")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *charBuilder) generate(w io.Writer, done map[string]bool) error {
|
||||||
|
if done[b.name] {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
done[b.name] = true
|
||||||
|
_, err := fmt.Fprintf(w, "var b%d = charBuilder{};", b.id)
|
||||||
|
return err
|
||||||
|
}
|
222
choice.go
222
choice.go
@ -1,23 +1,5 @@
|
|||||||
package treerack
|
package treerack
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
)
|
|
||||||
|
|
||||||
type choiceDefinition struct {
|
|
||||||
name string
|
|
||||||
id int
|
|
||||||
commit CommitType
|
|
||||||
options []string
|
|
||||||
optionDefs []definition
|
|
||||||
generalizations []int
|
|
||||||
cparser *choiceParser
|
|
||||||
cbuilder *choiceBuilder
|
|
||||||
validated bool
|
|
||||||
initialized bool
|
|
||||||
}
|
|
||||||
|
|
||||||
type choiceParser struct {
|
type choiceParser struct {
|
||||||
name string
|
name string
|
||||||
id int
|
id int
|
||||||
@ -33,127 +15,6 @@ type choiceBuilder struct {
|
|||||||
options []builder
|
options []builder
|
||||||
}
|
}
|
||||||
|
|
||||||
func newChoice(name string, ct CommitType, options []string) *choiceDefinition {
|
|
||||||
return &choiceDefinition{
|
|
||||||
name: name,
|
|
||||||
commit: ct,
|
|
||||||
options: options,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *choiceDefinition) nodeName() string { return d.name }
|
|
||||||
func (d *choiceDefinition) setName(n string) { d.name = n }
|
|
||||||
func (d *choiceDefinition) nodeID() int { return d.id }
|
|
||||||
func (d *choiceDefinition) setID(id int) { d.id = id }
|
|
||||||
func (d *choiceDefinition) commitType() CommitType { return d.commit }
|
|
||||||
func (d *choiceDefinition) setCommitType(ct CommitType) { d.commit = ct }
|
|
||||||
func (d *choiceDefinition) preinit() {}
|
|
||||||
|
|
||||||
func (d *choiceDefinition) validate(r *registry) error {
|
|
||||||
if d.validated {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
d.validated = true
|
|
||||||
for i := range d.options {
|
|
||||||
o, ok := r.definitions[d.options[i]]
|
|
||||||
if !ok {
|
|
||||||
return parserNotFound(d.options[i])
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := o.validate(r); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *choiceDefinition) createBuilder() {
|
|
||||||
d.cbuilder = &choiceBuilder{
|
|
||||||
name: d.name,
|
|
||||||
id: d.id,
|
|
||||||
commit: d.commit,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *choiceDefinition) initOptions(r *registry) {
|
|
||||||
for _, o := range d.options {
|
|
||||||
def := r.definitions[o]
|
|
||||||
d.optionDefs = append(d.optionDefs, def)
|
|
||||||
def.init(r)
|
|
||||||
d.cbuilder.options = append(d.cbuilder.options, def.builder())
|
|
||||||
def.addGeneralization(d.id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *choiceDefinition) init(r *registry) {
|
|
||||||
if d.initialized {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
d.initialized = true
|
|
||||||
d.createBuilder()
|
|
||||||
d.initOptions(r)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *choiceDefinition) addGeneralization(g int) {
|
|
||||||
if intsContain(d.generalizations, g) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
d.generalizations = append(d.generalizations, g)
|
|
||||||
for _, o := range d.optionDefs {
|
|
||||||
o.addGeneralization(g)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *choiceDefinition) createParser() {
|
|
||||||
d.cparser = &choiceParser{
|
|
||||||
name: d.name,
|
|
||||||
id: d.id,
|
|
||||||
commit: d.commit,
|
|
||||||
generalizations: d.generalizations,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *choiceDefinition) createOptionParsers() {
|
|
||||||
for _, def := range d.optionDefs {
|
|
||||||
option := def.parser()
|
|
||||||
d.cparser.options = append(d.cparser.options, option)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *choiceDefinition) parser() parser {
|
|
||||||
if d.cparser != nil {
|
|
||||||
return d.cparser
|
|
||||||
}
|
|
||||||
|
|
||||||
d.createParser()
|
|
||||||
d.createOptionParsers()
|
|
||||||
return d.cparser
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *choiceDefinition) builder() builder { return d.cbuilder }
|
|
||||||
|
|
||||||
func (d *choiceDefinition) format(r *registry, f formatFlags) string {
|
|
||||||
var chars []rune
|
|
||||||
for i := range d.options {
|
|
||||||
if i > 0 {
|
|
||||||
chars = append(chars, []rune(" | ")...)
|
|
||||||
}
|
|
||||||
|
|
||||||
optionDef, _ := r.definition(d.options[i])
|
|
||||||
if optionDef.commitType()&userDefined != 0 {
|
|
||||||
chars = append(chars, []rune(optionDef.nodeName())...)
|
|
||||||
} else {
|
|
||||||
chars = append(chars, []rune(optionDef.format(r, f))...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return string(chars)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *choiceParser) nodeName() string { return p.name }
|
func (p *choiceParser) nodeName() string { return p.name }
|
||||||
func (p *choiceParser) nodeID() int { return p.id }
|
func (p *choiceParser) nodeID() int { return p.id }
|
||||||
func (p *choiceParser) commitType() CommitType { return p.commit }
|
func (p *choiceParser) commitType() CommitType { return p.commit }
|
||||||
@ -248,50 +109,6 @@ func (p *choiceParser) parse(c *context) {
|
|||||||
c.results.unmarkPending(from, p.id)
|
c.results.unmarkPending(from, p.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *choiceParser) generate(w io.Writer, done map[string]bool) error {
|
|
||||||
if done[p.name] {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
done[p.name] = true
|
|
||||||
|
|
||||||
var err error
|
|
||||||
fprintf := func(f string, args ...interface{}) {
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = fmt.Fprintf(w, f, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf("var p%d = choiceParser{", p.id)
|
|
||||||
fprintf("id: %d, commit: %d,", p.id, p.commit)
|
|
||||||
if p.commitType()&userDefined != 0 {
|
|
||||||
fprintf("name: \"%s\",", p.name)
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf("generalizations: []int{")
|
|
||||||
for i := range p.generalizations {
|
|
||||||
fprintf("%d,", p.generalizations[i])
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf("}};")
|
|
||||||
|
|
||||||
for i := range p.options {
|
|
||||||
if err := p.options[i].generate(w, done); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf("p%d.options = []parser{", p.id)
|
|
||||||
for i := range p.options {
|
|
||||||
fprintf("&p%d,", p.options[i].nodeID())
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf("};")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *choiceBuilder) nodeName() string { return b.name }
|
func (b *choiceBuilder) nodeName() string { return b.name }
|
||||||
func (b *choiceBuilder) nodeID() int { return b.id }
|
func (b *choiceBuilder) nodeID() int { return b.id }
|
||||||
|
|
||||||
@ -339,42 +156,3 @@ func (b *choiceBuilder) build(c *context) ([]*Node, bool) {
|
|||||||
tokens: c.tokens,
|
tokens: c.tokens,
|
||||||
}}, true
|
}}, true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *choiceBuilder) generate(w io.Writer, done map[string]bool) error {
|
|
||||||
if done[b.name] {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
done[b.name] = true
|
|
||||||
|
|
||||||
var err error
|
|
||||||
fprintf := func(f string, args ...interface{}) {
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = fmt.Fprintf(w, f, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf("var b%d = choiceBuilder{", b.id)
|
|
||||||
fprintf("id: %d, commit: %d,", b.id, b.commit)
|
|
||||||
if b.commit&Alias == 0 {
|
|
||||||
fprintf("name: \"%s\",", b.name)
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf("};")
|
|
||||||
|
|
||||||
for i := range b.options {
|
|
||||||
if err := b.options[i].generate(w, done); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf("b%d.options = []builder{", b.id)
|
|
||||||
for i := range b.options {
|
|
||||||
fprintf("&b%d,", b.options[i].nodeID())
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf("};")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
223
choicedefine.go
Normal file
223
choicedefine.go
Normal file
@ -0,0 +1,223 @@
|
|||||||
|
package treerack
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
type choiceDefinition struct {
|
||||||
|
name string
|
||||||
|
id int
|
||||||
|
commit CommitType
|
||||||
|
options []string
|
||||||
|
optionDefs []definition
|
||||||
|
generalizations []int
|
||||||
|
cparser *choiceParser
|
||||||
|
cbuilder *choiceBuilder
|
||||||
|
validated bool
|
||||||
|
initialized bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *choiceDefinition) nodeName() string { return d.name }
|
||||||
|
func (d *choiceDefinition) setName(n string) { d.name = n }
|
||||||
|
func (d *choiceDefinition) nodeID() int { return d.id }
|
||||||
|
func (d *choiceDefinition) setID(id int) { d.id = id }
|
||||||
|
func (d *choiceDefinition) commitType() CommitType { return d.commit }
|
||||||
|
func (d *choiceDefinition) setCommitType(ct CommitType) { d.commit = ct }
|
||||||
|
func (d *choiceDefinition) preinit() {}
|
||||||
|
|
||||||
|
func newChoice(name string, ct CommitType, options []string) *choiceDefinition {
|
||||||
|
return &choiceDefinition{
|
||||||
|
name: name,
|
||||||
|
commit: ct,
|
||||||
|
options: options,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *choiceDefinition) validate(r *registry) error {
|
||||||
|
if d.validated {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
d.validated = true
|
||||||
|
for i := range d.options {
|
||||||
|
o, ok := r.definitions[d.options[i]]
|
||||||
|
if !ok {
|
||||||
|
return parserNotFound(d.options[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := o.validate(r); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *choiceDefinition) createBuilder() {
|
||||||
|
d.cbuilder = &choiceBuilder{
|
||||||
|
name: d.name,
|
||||||
|
id: d.id,
|
||||||
|
commit: d.commit,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *choiceDefinition) initOptions(r *registry) {
|
||||||
|
for _, o := range d.options {
|
||||||
|
def := r.definitions[o]
|
||||||
|
d.optionDefs = append(d.optionDefs, def)
|
||||||
|
def.init(r)
|
||||||
|
d.cbuilder.options = append(d.cbuilder.options, def.builder())
|
||||||
|
def.addGeneralization(d.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *choiceDefinition) init(r *registry) {
|
||||||
|
if d.initialized {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
d.initialized = true
|
||||||
|
d.createBuilder()
|
||||||
|
d.initOptions(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *choiceDefinition) addGeneralization(g int) {
|
||||||
|
if intsContain(d.generalizations, g) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
d.generalizations = append(d.generalizations, g)
|
||||||
|
for _, o := range d.optionDefs {
|
||||||
|
o.addGeneralization(g)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *choiceDefinition) createParser() {
|
||||||
|
d.cparser = &choiceParser{
|
||||||
|
name: d.name,
|
||||||
|
id: d.id,
|
||||||
|
commit: d.commit,
|
||||||
|
generalizations: d.generalizations,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *choiceDefinition) createOptionParsers() {
|
||||||
|
for _, def := range d.optionDefs {
|
||||||
|
option := def.parser()
|
||||||
|
d.cparser.options = append(d.cparser.options, option)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *choiceDefinition) parser() parser {
|
||||||
|
if d.cparser != nil {
|
||||||
|
return d.cparser
|
||||||
|
}
|
||||||
|
|
||||||
|
d.createParser()
|
||||||
|
d.createOptionParsers()
|
||||||
|
return d.cparser
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *choiceDefinition) builder() builder { return d.cbuilder }
|
||||||
|
|
||||||
|
func (d *choiceDefinition) format(r *registry, f formatFlags) string {
|
||||||
|
var chars []rune
|
||||||
|
for i := range d.options {
|
||||||
|
if i > 0 {
|
||||||
|
chars = append(chars, []rune(" | ")...)
|
||||||
|
}
|
||||||
|
|
||||||
|
optionDef, _ := r.definition(d.options[i])
|
||||||
|
if optionDef.commitType()&userDefined != 0 {
|
||||||
|
chars = append(chars, []rune(optionDef.nodeName())...)
|
||||||
|
} else {
|
||||||
|
chars = append(chars, []rune(optionDef.format(r, f))...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(chars)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *choiceParser) generate(w io.Writer, done map[string]bool) error {
|
||||||
|
if done[p.name] {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
done[p.name] = true
|
||||||
|
|
||||||
|
var err error
|
||||||
|
fprintf := func(f string, args ...interface{}) {
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = fmt.Fprintf(w, f, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf("var p%d = choiceParser{", p.id)
|
||||||
|
fprintf("id: %d, commit: %d,", p.id, p.commit)
|
||||||
|
if p.commitType()&userDefined != 0 {
|
||||||
|
fprintf("name: \"%s\",", p.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf("generalizations: []int{")
|
||||||
|
for i := range p.generalizations {
|
||||||
|
fprintf("%d,", p.generalizations[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf("}};")
|
||||||
|
|
||||||
|
for i := range p.options {
|
||||||
|
if err := p.options[i].(generator).generate(w, done); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf("p%d.options = []parser{", p.id)
|
||||||
|
for i := range p.options {
|
||||||
|
fprintf("&p%d,", p.options[i].nodeID())
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf("};")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *choiceBuilder) generate(w io.Writer, done map[string]bool) error {
|
||||||
|
if done[b.name] {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
done[b.name] = true
|
||||||
|
|
||||||
|
var err error
|
||||||
|
fprintf := func(f string, args ...interface{}) {
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = fmt.Fprintf(w, f, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf("var b%d = choiceBuilder{", b.id)
|
||||||
|
fprintf("id: %d, commit: %d,", b.id, b.commit)
|
||||||
|
if b.commit&Alias == 0 {
|
||||||
|
fprintf("name: \"%s\",", b.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf("};")
|
||||||
|
|
||||||
|
for i := range b.options {
|
||||||
|
if err := b.options[i].(generator).generate(w, done); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf("b%d.options = []builder{", b.id)
|
||||||
|
for i := range b.options {
|
||||||
|
fprintf("&b%d,", b.options[i].nodeID())
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf("};")
|
||||||
|
return err
|
||||||
|
}
|
@ -130,14 +130,14 @@ func (c *context) parseError(p parser) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) finalizeParse(root parser) error {
|
func (c *context) finalizeParse(root parser) error {
|
||||||
p := c.failingParser
|
fp := c.failingParser
|
||||||
if p == nil {
|
if fp == nil {
|
||||||
p = root
|
fp = root
|
||||||
}
|
}
|
||||||
|
|
||||||
to, match, found := c.results.longestResult(0, root.nodeID())
|
to, match, found := c.results.longestResult(0, root.nodeID())
|
||||||
if !found || !match || found && match && to < c.readOffset {
|
if !found || !match || found && match && to < c.readOffset {
|
||||||
return c.parseError(p)
|
return c.parseError(fp)
|
||||||
}
|
}
|
||||||
|
|
||||||
c.read()
|
c.read()
|
||||||
|
23
gendoc.go
Normal file
23
gendoc.go
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
package treerack
|
||||||
|
|
||||||
|
// The below doc doesn't apply to treerack's source code
|
||||||
|
// only to the source code generated with treerack.
|
||||||
|
const gendoc = `
|
||||||
|
/*
|
||||||
|
This file was generated by treerack (https://github.com/aryszka/treerack).
|
||||||
|
|
||||||
|
The contents of this file fall under different licenses.
|
||||||
|
|
||||||
|
The code between the "// head" and "// eo head" lines falls under the same
|
||||||
|
license as the source code of treerack (https://github.com/aryszka/treerack),
|
||||||
|
unless explicitly stated otherwise, if treerack's license allows changing the
|
||||||
|
license of this source code.
|
||||||
|
|
||||||
|
Treerack's license: MIT https://opensource.org/licenses/MIT
|
||||||
|
where YEAR=2018, COPYRIGHT HOLDER=Arpad Ryszka (arpad.ryszka@gmail.com)
|
||||||
|
|
||||||
|
The rest of the content of this file falls under the same license as the one
|
||||||
|
that the user of treerack generating this file declares for it, or it is
|
||||||
|
unlicensed.
|
||||||
|
*/
|
||||||
|
`
|
26
node.go
26
node.go
@ -1,13 +1,6 @@
|
|||||||
package treerack
|
package treerack
|
||||||
|
|
||||||
import "fmt"
|
import "github.com/aryszka/treerack/self"
|
||||||
|
|
||||||
type Node struct {
|
|
||||||
Name string
|
|
||||||
Nodes []*Node
|
|
||||||
From, To int
|
|
||||||
tokens []rune
|
|
||||||
}
|
|
||||||
|
|
||||||
func mapNodes(m func(n *Node) *Node, n []*Node) []*Node {
|
func mapNodes(m func(n *Node) *Node, n []*Node) []*Node {
|
||||||
var nn []*Node
|
var nn []*Node
|
||||||
@ -29,10 +22,17 @@ func filterNodes(f func(n *Node) bool, n []*Node) []*Node {
|
|||||||
return nn
|
return nn
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) String() string {
|
func mapSelfNode(n *self.Node) *Node {
|
||||||
return fmt.Sprintf("%s:%d:%d:%s", n.Name, n.From, n.To, n.Text())
|
nn := Node{
|
||||||
}
|
Name: n.Name,
|
||||||
|
From: n.From,
|
||||||
|
To: n.To,
|
||||||
|
tokens: n.Tokens(),
|
||||||
|
}
|
||||||
|
|
||||||
func (n *Node) Text() string {
|
for i := range n.Nodes {
|
||||||
return string(n.tokens[n.From:n.To])
|
nn.Nodes = append(nn.Nodes, mapSelfNode(n.Nodes[i]))
|
||||||
|
}
|
||||||
|
|
||||||
|
return &nn
|
||||||
}
|
}
|
||||||
|
28
nodehead.go
Normal file
28
nodehead.go
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
package treerack
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
type Node struct {
|
||||||
|
Name string
|
||||||
|
Nodes []*Node
|
||||||
|
From, To int
|
||||||
|
tokens []rune
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) Tokens() []rune {
|
||||||
|
defer func() {
|
||||||
|
if err := recover(); err != nil {
|
||||||
|
println(len(n.tokens), n.From, n.To)
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
return n.tokens
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) String() string {
|
||||||
|
return fmt.Sprintf("%s:%d:%d:%s", n.Name, n.From, n.To, n.Text())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) Text() string {
|
||||||
|
return string(n.Tokens()[n.From:n.To])
|
||||||
|
}
|
@ -34,6 +34,8 @@ test all docs
|
|||||||
warn nows usage in docs, e.g. spaces in symbol = [a-z]+
|
warn nows usage in docs, e.g. spaces in symbol = [a-z]+
|
||||||
test error report on invalid flag
|
test error report on invalid flag
|
||||||
report unused definitions
|
report unused definitions
|
||||||
|
simplify generated output
|
||||||
|
parse hashed, storing only the results
|
||||||
|
|
||||||
[optimization]
|
[optimization]
|
||||||
try preallocate larger store chunks
|
try preallocate larger store chunks
|
||||||
|
625
parsegen.go
625
parsegen.go
@ -1,625 +0,0 @@
|
|||||||
package treerack
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"io"
|
|
||||||
)
|
|
||||||
|
|
||||||
func parsegen(r io.Reader) (*Node, error) {
|
|
||||||
var p188 = sequenceParser{id: 188, commit: 32, allChars: false, ranges: [][]int{{0, -1}, {1, 1}, {0, -1}}, generalizations: []int{}}
|
|
||||||
var p186 = choiceParser{id: 186, commit: 2, generalizations: []int{}}
|
|
||||||
var p185 = choiceParser{id: 185, commit: 70, name: "wsc", generalizations: []int{186}}
|
|
||||||
var p171 = choiceParser{id: 171, commit: 66, name: "wschar", generalizations: []int{185, 186}}
|
|
||||||
var p63 = sequenceParser{id: 63, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{171, 185, 186}}
|
|
||||||
var p28 = charParser{id: 28, not: false, chars: []rune{32}, ranges: [][]rune{}}
|
|
||||||
p63.items = []parser{&p28}
|
|
||||||
var p121 = sequenceParser{id: 121, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{171, 185, 186}}
|
|
||||||
var p17 = charParser{id: 17, not: false, chars: []rune{9}, ranges: [][]rune{}}
|
|
||||||
p121.items = []parser{&p17}
|
|
||||||
var p79 = sequenceParser{id: 79, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{171, 185, 186}}
|
|
||||||
var p53 = charParser{id: 53, not: false, chars: []rune{10}, ranges: [][]rune{}}
|
|
||||||
p79.items = []parser{&p53}
|
|
||||||
var p114 = sequenceParser{id: 114, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{171, 185, 186}}
|
|
||||||
var p96 = charParser{id: 96, not: false, chars: []rune{8}, ranges: [][]rune{}}
|
|
||||||
p114.items = []parser{&p96}
|
|
||||||
var p141 = sequenceParser{id: 141, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{171, 185, 186}}
|
|
||||||
var p9 = charParser{id: 9, not: false, chars: []rune{12}, ranges: [][]rune{}}
|
|
||||||
p141.items = []parser{&p9}
|
|
||||||
var p47 = sequenceParser{id: 47, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{171, 185, 186}}
|
|
||||||
var p87 = charParser{id: 87, not: false, chars: []rune{13}, ranges: [][]rune{}}
|
|
||||||
p47.items = []parser{&p87}
|
|
||||||
var p40 = sequenceParser{id: 40, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{171, 185, 186}}
|
|
||||||
var p18 = charParser{id: 18, not: false, chars: []rune{11}, ranges: [][]rune{}}
|
|
||||||
p40.items = []parser{&p18}
|
|
||||||
p171.options = []parser{&p63, &p121, &p79, &p114, &p141, &p47, &p40}
|
|
||||||
var p90 = sequenceParser{id: 90, commit: 72, allChars: false, name: "comment", ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {0, -1}}, generalizations: []int{185, 186}}
|
|
||||||
var p142 = choiceParser{id: 142, commit: 74, name: "comment-segment", generalizations: []int{}}
|
|
||||||
var p80 = sequenceParser{id: 80, commit: 74, allChars: false, name: "line-comment", ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {0, -1}}, generalizations: []int{142}}
|
|
||||||
var p41 = sequenceParser{id: 41, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}}, generalizations: []int{}}
|
|
||||||
var p65 = charParser{id: 65, not: false, chars: []rune{47}, ranges: [][]rune{}}
|
|
||||||
var p148 = charParser{id: 148, not: false, chars: []rune{47}, ranges: [][]rune{}}
|
|
||||||
p41.items = []parser{&p65, &p148}
|
|
||||||
var p55 = sequenceParser{id: 55, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{}}
|
|
||||||
var p124 = charParser{id: 124, not: true, chars: []rune{10}, ranges: [][]rune{}}
|
|
||||||
p55.items = []parser{&p124}
|
|
||||||
p80.items = []parser{&p41, &p55}
|
|
||||||
var p48 = sequenceParser{id: 48, commit: 74, allChars: false, name: "block-comment", ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {1, 1}, {0, -1}, {1, 1}}, generalizations: []int{142}}
|
|
||||||
var p97 = sequenceParser{id: 97, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}}, generalizations: []int{}}
|
|
||||||
var p64 = charParser{id: 64, not: false, chars: []rune{47}, ranges: [][]rune{}}
|
|
||||||
var p54 = charParser{id: 54, not: false, chars: []rune{42}, ranges: [][]rune{}}
|
|
||||||
p97.items = []parser{&p64, &p54}
|
|
||||||
var p89 = choiceParser{id: 89, commit: 10, generalizations: []int{}}
|
|
||||||
var p104 = sequenceParser{id: 104, commit: 10, allChars: false, ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}}, generalizations: []int{89}}
|
|
||||||
var p29 = sequenceParser{id: 29, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{}}
|
|
||||||
var p88 = charParser{id: 88, not: false, chars: []rune{42}, ranges: [][]rune{}}
|
|
||||||
p29.items = []parser{&p88}
|
|
||||||
var p122 = sequenceParser{id: 122, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{}}
|
|
||||||
var p131 = charParser{id: 131, not: true, chars: []rune{47}, ranges: [][]rune{}}
|
|
||||||
p122.items = []parser{&p131}
|
|
||||||
p104.items = []parser{&p29, &p122}
|
|
||||||
var p159 = sequenceParser{id: 159, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{89}}
|
|
||||||
var p123 = charParser{id: 123, not: true, chars: []rune{42}, ranges: [][]rune{}}
|
|
||||||
p159.items = []parser{&p123}
|
|
||||||
p89.options = []parser{&p104, &p159}
|
|
||||||
var p19 = sequenceParser{id: 19, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}}, generalizations: []int{}}
|
|
||||||
var p153 = charParser{id: 153, not: false, chars: []rune{42}, ranges: [][]rune{}}
|
|
||||||
var p24 = charParser{id: 24, not: false, chars: []rune{47}, ranges: [][]rune{}}
|
|
||||||
p19.items = []parser{&p153, &p24}
|
|
||||||
p48.items = []parser{&p97, &p89, &p19}
|
|
||||||
p142.options = []parser{&p80, &p48}
|
|
||||||
var p3 = sequenceParser{id: 3, commit: 10, allChars: false, ranges: [][]int{{0, -1}, {0, 1}, {0, -1}, {1, 1}, {0, -1}, {0, 1}, {0, -1}, {1, 1}}, generalizations: []int{}}
|
|
||||||
var p160 = choiceParser{id: 160, commit: 74, name: "ws-no-nl", generalizations: []int{}}
|
|
||||||
var p66 = sequenceParser{id: 66, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{160}}
|
|
||||||
var p109 = charParser{id: 109, not: false, chars: []rune{32}, ranges: [][]rune{}}
|
|
||||||
p66.items = []parser{&p109}
|
|
||||||
var p180 = sequenceParser{id: 180, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{160}}
|
|
||||||
var p30 = charParser{id: 30, not: false, chars: []rune{9}, ranges: [][]rune{}}
|
|
||||||
p180.items = []parser{&p30}
|
|
||||||
var p136 = sequenceParser{id: 136, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{160}}
|
|
||||||
var p125 = charParser{id: 125, not: false, chars: []rune{8}, ranges: [][]rune{}}
|
|
||||||
p136.items = []parser{&p125}
|
|
||||||
var p118 = sequenceParser{id: 118, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{160}}
|
|
||||||
var p31 = charParser{id: 31, not: false, chars: []rune{12}, ranges: [][]rune{}}
|
|
||||||
p118.items = []parser{&p31}
|
|
||||||
var p49 = sequenceParser{id: 49, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{160}}
|
|
||||||
var p73 = charParser{id: 73, not: false, chars: []rune{13}, ranges: [][]rune{}}
|
|
||||||
p49.items = []parser{&p73}
|
|
||||||
var p182 = sequenceParser{id: 182, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{160}}
|
|
||||||
var p181 = charParser{id: 181, not: false, chars: []rune{11}, ranges: [][]rune{}}
|
|
||||||
p182.items = []parser{&p181}
|
|
||||||
p160.options = []parser{&p66, &p180, &p136, &p118, &p49, &p182}
|
|
||||||
var p137 = sequenceParser{id: 137, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{}}
|
|
||||||
var p105 = charParser{id: 105, not: false, chars: []rune{10}, ranges: [][]rune{}}
|
|
||||||
p137.items = []parser{&p105}
|
|
||||||
p3.items = []parser{&p160, &p137, &p160, &p142}
|
|
||||||
p90.items = []parser{&p142, &p3}
|
|
||||||
p185.options = []parser{&p171, &p90}
|
|
||||||
p186.options = []parser{&p185}
|
|
||||||
var p187 = sequenceParser{id: 187, commit: 66, allChars: false, name: "syntax:wsroot", ranges: [][]int{{0, 1}, {0, -1}, {0, 1}, {0, 1}}, generalizations: []int{}}
|
|
||||||
var p70 = sequenceParser{id: 70, commit: 2, allChars: false, ranges: [][]int{{1, 1}, {0, -1}}, generalizations: []int{}}
|
|
||||||
var p36 = sequenceParser{id: 36, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{}}
|
|
||||||
var p140 = charParser{id: 140, not: false, chars: []rune{59}, ranges: [][]rune{}}
|
|
||||||
p36.items = []parser{&p140}
|
|
||||||
var p69 = sequenceParser{id: 69, commit: 2, allChars: false, ranges: [][]int{{0, -1}, {1, 1}}, generalizations: []int{}}
|
|
||||||
p69.items = []parser{&p186, &p36}
|
|
||||||
p70.items = []parser{&p36, &p69}
|
|
||||||
var p35 = sequenceParser{id: 35, commit: 66, allChars: false, name: "definitions", ranges: [][]int{{1, 1}, {0, 1}}, generalizations: []int{}}
|
|
||||||
var p165 = sequenceParser{id: 165, commit: 64, allChars: false, name: "definition", ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {0, -1}, {1, 1}}, generalizations: []int{}}
|
|
||||||
var p95 = sequenceParser{id: 95, commit: 74, allChars: false, name: "definition-name", ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {0, -1}}, generalizations: []int{}}
|
|
||||||
var p42 = sequenceParser{id: 42, commit: 72, allChars: false, name: "symbol", ranges: [][]int{{1, -1}, {1, -1}}, generalizations: []int{14, 128, 94}}
|
|
||||||
var p144 = sequenceParser{id: 144, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{}}
|
|
||||||
var p169 = charParser{id: 169, not: true, chars: []rune{92, 32, 10, 9, 8, 12, 13, 11, 47, 46, 91, 93, 34, 123, 125, 94, 43, 42, 63, 124, 40, 41, 58, 61, 59}, ranges: [][]rune{}}
|
|
||||||
p144.items = []parser{&p169}
|
|
||||||
p42.items = []parser{&p144}
|
|
||||||
var p77 = sequenceParser{id: 77, commit: 10, allChars: false, ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}}, generalizations: []int{}}
|
|
||||||
var p155 = sequenceParser{id: 155, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{}}
|
|
||||||
var p147 = charParser{id: 147, not: false, chars: []rune{58}, ranges: [][]rune{}}
|
|
||||||
p155.items = []parser{&p147}
|
|
||||||
var p52 = choiceParser{id: 52, commit: 66, name: "flag", generalizations: []int{}}
|
|
||||||
var p139 = sequenceParser{id: 139, commit: 72, allChars: true, name: "alias", ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}}, generalizations: []int{52}}
|
|
||||||
var p15 = charParser{id: 15, not: false, chars: []rune{97}, ranges: [][]rune{}}
|
|
||||||
var p99 = charParser{id: 99, not: false, chars: []rune{108}, ranges: [][]rune{}}
|
|
||||||
var p174 = charParser{id: 174, not: false, chars: []rune{105}, ranges: [][]rune{}}
|
|
||||||
var p135 = charParser{id: 135, not: false, chars: []rune{97}, ranges: [][]rune{}}
|
|
||||||
var p16 = charParser{id: 16, not: false, chars: []rune{115}, ranges: [][]rune{}}
|
|
||||||
p139.items = []parser{&p15, &p99, &p174, &p135, &p16}
|
|
||||||
var p157 = sequenceParser{id: 157, commit: 72, allChars: true, name: "ws", ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}}, generalizations: []int{52}}
|
|
||||||
var p43 = charParser{id: 43, not: false, chars: []rune{119}, ranges: [][]rune{}}
|
|
||||||
var p39 = charParser{id: 39, not: false, chars: []rune{115}, ranges: [][]rune{}}
|
|
||||||
p157.items = []parser{&p43, &p39}
|
|
||||||
var p116 = sequenceParser{id: 116, commit: 72, allChars: true, name: "nows", ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}}, generalizations: []int{52}}
|
|
||||||
var p22 = charParser{id: 22, not: false, chars: []rune{110}, ranges: [][]rune{}}
|
|
||||||
var p145 = charParser{id: 145, not: false, chars: []rune{111}, ranges: [][]rune{}}
|
|
||||||
var p113 = charParser{id: 113, not: false, chars: []rune{119}, ranges: [][]rune{}}
|
|
||||||
var p1 = charParser{id: 1, not: false, chars: []rune{115}, ranges: [][]rune{}}
|
|
||||||
p116.items = []parser{&p22, &p145, &p113, &p1}
|
|
||||||
var p2 = sequenceParser{id: 2, commit: 72, allChars: true, name: "failpass", ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}}, generalizations: []int{52}}
|
|
||||||
var p23 = charParser{id: 23, not: false, chars: []rune{102}, ranges: [][]rune{}}
|
|
||||||
var p82 = charParser{id: 82, not: false, chars: []rune{97}, ranges: [][]rune{}}
|
|
||||||
var p62 = charParser{id: 62, not: false, chars: []rune{105}, ranges: [][]rune{}}
|
|
||||||
var p59 = charParser{id: 59, not: false, chars: []rune{108}, ranges: [][]rune{}}
|
|
||||||
var p44 = charParser{id: 44, not: false, chars: []rune{112}, ranges: [][]rune{}}
|
|
||||||
var p100 = charParser{id: 100, not: false, chars: []rune{97}, ranges: [][]rune{}}
|
|
||||||
var p158 = charParser{id: 158, not: false, chars: []rune{115}, ranges: [][]rune{}}
|
|
||||||
var p103 = charParser{id: 103, not: false, chars: []rune{115}, ranges: [][]rune{}}
|
|
||||||
p2.items = []parser{&p23, &p82, &p62, &p59, &p44, &p100, &p158, &p103}
|
|
||||||
var p177 = sequenceParser{id: 177, commit: 72, allChars: true, name: "root", ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}}, generalizations: []int{52}}
|
|
||||||
var p76 = charParser{id: 76, not: false, chars: []rune{114}, ranges: [][]rune{}}
|
|
||||||
var p83 = charParser{id: 83, not: false, chars: []rune{111}, ranges: [][]rune{}}
|
|
||||||
var p78 = charParser{id: 78, not: false, chars: []rune{111}, ranges: [][]rune{}}
|
|
||||||
var p45 = charParser{id: 45, not: false, chars: []rune{116}, ranges: [][]rune{}}
|
|
||||||
p177.items = []parser{&p76, &p83, &p78, &p45}
|
|
||||||
p52.options = []parser{&p139, &p157, &p116, &p2, &p177}
|
|
||||||
p77.items = []parser{&p155, &p52}
|
|
||||||
p95.items = []parser{&p42, &p77}
|
|
||||||
var p13 = sequenceParser{id: 13, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{}}
|
|
||||||
var p117 = charParser{id: 117, not: false, chars: []rune{61}, ranges: [][]rune{}}
|
|
||||||
p13.items = []parser{&p117}
|
|
||||||
var p14 = choiceParser{id: 14, commit: 66, name: "expression", generalizations: []int{}}
|
|
||||||
var p168 = choiceParser{id: 168, commit: 66, name: "terminal", generalizations: []int{14, 128, 94}}
|
|
||||||
var p91 = sequenceParser{id: 91, commit: 72, allChars: true, name: "any-char", ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{168, 14, 128, 94}}
|
|
||||||
var p106 = charParser{id: 106, not: false, chars: []rune{46}, ranges: [][]rune{}}
|
|
||||||
p91.items = []parser{&p106}
|
|
||||||
var p143 = sequenceParser{id: 143, commit: 72, allChars: false, name: "char-class", ranges: [][]int{{1, 1}, {0, 1}, {0, -1}, {1, 1}, {1, 1}, {0, 1}, {0, -1}, {1, 1}}, generalizations: []int{168, 14, 128, 94}}
|
|
||||||
var p111 = sequenceParser{id: 111, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{}}
|
|
||||||
var p81 = charParser{id: 81, not: false, chars: []rune{91}, ranges: [][]rune{}}
|
|
||||||
p111.items = []parser{&p81}
|
|
||||||
var p50 = sequenceParser{id: 50, commit: 72, allChars: true, name: "class-not", ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{}}
|
|
||||||
var p119 = charParser{id: 119, not: false, chars: []rune{94}, ranges: [][]rune{}}
|
|
||||||
p50.items = []parser{&p119}
|
|
||||||
var p149 = choiceParser{id: 149, commit: 10, generalizations: []int{}}
|
|
||||||
var p98 = choiceParser{id: 98, commit: 72, name: "class-char", generalizations: []int{149}}
|
|
||||||
var p166 = sequenceParser{id: 166, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{98, 149}}
|
|
||||||
var p107 = charParser{id: 107, not: true, chars: []rune{92, 91, 93, 94, 45}, ranges: [][]rune{}}
|
|
||||||
p166.items = []parser{&p107}
|
|
||||||
var p110 = sequenceParser{id: 110, commit: 10, allChars: false, ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}}, generalizations: []int{98, 149}}
|
|
||||||
var p133 = sequenceParser{id: 133, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{}}
|
|
||||||
var p132 = charParser{id: 132, not: false, chars: []rune{92}, ranges: [][]rune{}}
|
|
||||||
p133.items = []parser{&p132}
|
|
||||||
var p162 = sequenceParser{id: 162, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{}}
|
|
||||||
var p161 = charParser{id: 161, not: true, chars: []rune{}, ranges: [][]rune{}}
|
|
||||||
p162.items = []parser{&p161}
|
|
||||||
p110.items = []parser{&p133, &p162}
|
|
||||||
p98.options = []parser{&p166, &p110}
|
|
||||||
var p4 = sequenceParser{id: 4, commit: 72, allChars: false, name: "char-range", ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}}, generalizations: []int{149}}
|
|
||||||
var p167 = sequenceParser{id: 167, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{}}
|
|
||||||
var p175 = charParser{id: 175, not: false, chars: []rune{45}, ranges: [][]rune{}}
|
|
||||||
p167.items = []parser{&p175}
|
|
||||||
p4.items = []parser{&p98, &p167, &p98}
|
|
||||||
p149.options = []parser{&p98, &p4}
|
|
||||||
var p5 = sequenceParser{id: 5, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{}}
|
|
||||||
var p183 = charParser{id: 183, not: false, chars: []rune{93}, ranges: [][]rune{}}
|
|
||||||
p5.items = []parser{&p183}
|
|
||||||
p143.items = []parser{&p111, &p50, &p149, &p5}
|
|
||||||
var p84 = sequenceParser{id: 84, commit: 72, allChars: false, name: "char-sequence", ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {1, 1}, {0, -1}, {1, 1}}, generalizations: []int{168, 14, 128, 94}}
|
|
||||||
var p101 = sequenceParser{id: 101, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{}}
|
|
||||||
var p150 = charParser{id: 150, not: false, chars: []rune{34}, ranges: [][]rune{}}
|
|
||||||
p101.items = []parser{&p150}
|
|
||||||
var p172 = choiceParser{id: 172, commit: 72, name: "sequence-char", generalizations: []int{}}
|
|
||||||
var p67 = sequenceParser{id: 67, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{172}}
|
|
||||||
var p74 = charParser{id: 74, not: true, chars: []rune{92, 34}, ranges: [][]rune{}}
|
|
||||||
p67.items = []parser{&p74}
|
|
||||||
var p32 = sequenceParser{id: 32, commit: 10, allChars: false, ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}}, generalizations: []int{172}}
|
|
||||||
var p108 = sequenceParser{id: 108, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{}}
|
|
||||||
var p184 = charParser{id: 184, not: false, chars: []rune{92}, ranges: [][]rune{}}
|
|
||||||
p108.items = []parser{&p184}
|
|
||||||
var p10 = sequenceParser{id: 10, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{}}
|
|
||||||
var p68 = charParser{id: 68, not: true, chars: []rune{}, ranges: [][]rune{}}
|
|
||||||
p10.items = []parser{&p68}
|
|
||||||
p32.items = []parser{&p108, &p10}
|
|
||||||
p172.options = []parser{&p67, &p32}
|
|
||||||
var p25 = sequenceParser{id: 25, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{}}
|
|
||||||
var p37 = charParser{id: 37, not: false, chars: []rune{34}, ranges: [][]rune{}}
|
|
||||||
p25.items = []parser{&p37}
|
|
||||||
p84.items = []parser{&p101, &p172, &p25}
|
|
||||||
p168.options = []parser{&p91, &p143, &p84}
|
|
||||||
var p21 = sequenceParser{id: 21, commit: 66, allChars: false, name: "group", ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {0, -1}, {1, 1}}, generalizations: []int{14, 128, 94}}
|
|
||||||
var p154 = sequenceParser{id: 154, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{}}
|
|
||||||
var p56 = charParser{id: 56, not: false, chars: []rune{40}, ranges: [][]rune{}}
|
|
||||||
p154.items = []parser{&p56}
|
|
||||||
var p120 = sequenceParser{id: 120, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{}}
|
|
||||||
var p20 = charParser{id: 20, not: false, chars: []rune{41}, ranges: [][]rune{}}
|
|
||||||
p120.items = []parser{&p20}
|
|
||||||
p21.items = []parser{&p154, &p186, &p14, &p186, &p120}
|
|
||||||
var p8 = sequenceParser{id: 8, commit: 64, allChars: false, name: "sequence", ranges: [][]int{{1, 1}, {0, -1}}, generalizations: []int{14, 94}}
|
|
||||||
var p115 = sequenceParser{id: 115, commit: 72, allChars: false, name: "item", ranges: [][]int{{1, 1}, {0, 1}, {1, 1}, {0, 1}}, generalizations: []int{}}
|
|
||||||
var p128 = choiceParser{id: 128, commit: 10, generalizations: []int{}}
|
|
||||||
p128.options = []parser{&p168, &p42, &p21}
|
|
||||||
var p179 = choiceParser{id: 179, commit: 66, name: "quantity", generalizations: []int{}}
|
|
||||||
var p152 = sequenceParser{id: 152, commit: 64, allChars: false, name: "count-quantifier", ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {0, -1}, {1, 1}}, generalizations: []int{179}}
|
|
||||||
var p170 = sequenceParser{id: 170, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{}}
|
|
||||||
var p151 = charParser{id: 151, not: false, chars: []rune{123}, ranges: [][]rune{}}
|
|
||||||
p170.items = []parser{&p151}
|
|
||||||
var p127 = sequenceParser{id: 127, commit: 64, allChars: false, name: "count", ranges: [][]int{{1, 1}}, generalizations: []int{}}
|
|
||||||
var p51 = sequenceParser{id: 51, commit: 74, allChars: false, name: "number", ranges: [][]int{{1, -1}, {1, -1}}, generalizations: []int{}}
|
|
||||||
var p176 = sequenceParser{id: 176, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{}}
|
|
||||||
var p126 = charParser{id: 126, not: false, chars: []rune{}, ranges: [][]rune{{48, 57}}}
|
|
||||||
p176.items = []parser{&p126}
|
|
||||||
p51.items = []parser{&p176}
|
|
||||||
p127.items = []parser{&p51}
|
|
||||||
var p6 = sequenceParser{id: 6, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{}}
|
|
||||||
var p26 = charParser{id: 26, not: false, chars: []rune{125}, ranges: [][]rune{}}
|
|
||||||
p6.items = []parser{&p26}
|
|
||||||
p152.items = []parser{&p170, &p186, &p127, &p186, &p6}
|
|
||||||
var p92 = sequenceParser{id: 92, commit: 64, allChars: false, name: "range-quantifier", ranges: [][]int{{1, 1}, {0, -1}, {0, 1}, {0, -1}, {1, 1}, {0, -1}, {0, 1}, {0, -1}, {1, 1}}, generalizations: []int{179}}
|
|
||||||
var p85 = sequenceParser{id: 85, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{}}
|
|
||||||
var p75 = charParser{id: 75, not: false, chars: []rune{123}, ranges: [][]rune{}}
|
|
||||||
p85.items = []parser{&p75}
|
|
||||||
var p102 = sequenceParser{id: 102, commit: 64, allChars: false, name: "range-from", ranges: [][]int{{1, 1}}, generalizations: []int{}}
|
|
||||||
p102.items = []parser{&p51}
|
|
||||||
var p112 = sequenceParser{id: 112, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{}}
|
|
||||||
var p86 = charParser{id: 86, not: false, chars: []rune{44}, ranges: [][]rune{}}
|
|
||||||
p112.items = []parser{&p86}
|
|
||||||
var p138 = sequenceParser{id: 138, commit: 64, allChars: false, name: "range-to", ranges: [][]int{{1, 1}}, generalizations: []int{}}
|
|
||||||
p138.items = []parser{&p51}
|
|
||||||
var p57 = sequenceParser{id: 57, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{}}
|
|
||||||
var p58 = charParser{id: 58, not: false, chars: []rune{125}, ranges: [][]rune{}}
|
|
||||||
p57.items = []parser{&p58}
|
|
||||||
p92.items = []parser{&p85, &p186, &p102, &p186, &p112, &p186, &p138, &p186, &p57}
|
|
||||||
var p38 = sequenceParser{id: 38, commit: 72, allChars: true, name: "one-or-more", ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{179}}
|
|
||||||
var p163 = charParser{id: 163, not: false, chars: []rune{43}, ranges: [][]rune{}}
|
|
||||||
p38.items = []parser{&p163}
|
|
||||||
var p178 = sequenceParser{id: 178, commit: 72, allChars: true, name: "zero-or-more", ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{179}}
|
|
||||||
var p93 = charParser{id: 93, not: false, chars: []rune{42}, ranges: [][]rune{}}
|
|
||||||
p178.items = []parser{&p93}
|
|
||||||
var p156 = sequenceParser{id: 156, commit: 72, allChars: true, name: "zero-or-one", ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{179}}
|
|
||||||
var p146 = charParser{id: 146, not: false, chars: []rune{63}, ranges: [][]rune{}}
|
|
||||||
p156.items = []parser{&p146}
|
|
||||||
p179.options = []parser{&p152, &p92, &p38, &p178, &p156}
|
|
||||||
p115.items = []parser{&p128, &p179}
|
|
||||||
var p7 = sequenceParser{id: 7, commit: 2, allChars: false, ranges: [][]int{{0, -1}, {1, 1}}, generalizations: []int{}}
|
|
||||||
p7.items = []parser{&p186, &p115}
|
|
||||||
p8.items = []parser{&p115, &p7}
|
|
||||||
var p61 = sequenceParser{id: 61, commit: 64, allChars: false, name: "choice", ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {0, -1}}, generalizations: []int{14}}
|
|
||||||
var p94 = choiceParser{id: 94, commit: 66, name: "option", generalizations: []int{}}
|
|
||||||
p94.options = []parser{&p168, &p42, &p21, &p8}
|
|
||||||
var p11 = sequenceParser{id: 11, commit: 2, allChars: false, ranges: [][]int{{1, 1}, {0, -1}, {1, 1}}, generalizations: []int{}}
|
|
||||||
var p134 = sequenceParser{id: 134, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{}}
|
|
||||||
var p173 = charParser{id: 173, not: false, chars: []rune{124}, ranges: [][]rune{}}
|
|
||||||
p134.items = []parser{&p173}
|
|
||||||
p11.items = []parser{&p134, &p186, &p94}
|
|
||||||
var p60 = sequenceParser{id: 60, commit: 2, allChars: false, ranges: [][]int{{0, -1}, {1, 1}}, generalizations: []int{}}
|
|
||||||
p60.items = []parser{&p186, &p11}
|
|
||||||
p61.items = []parser{&p94, &p186, &p11, &p60}
|
|
||||||
p14.options = []parser{&p168, &p42, &p21, &p8, &p61}
|
|
||||||
p165.items = []parser{&p95, &p186, &p13, &p186, &p14}
|
|
||||||
var p34 = sequenceParser{id: 34, commit: 2, allChars: false, ranges: [][]int{{0, -1}, {1, 1}, {0, -1}}, generalizations: []int{}}
|
|
||||||
var p130 = sequenceParser{id: 130, commit: 2, allChars: false, ranges: [][]int{{1, 1}, {0, -1}, {0, -1}, {1, 1}}, generalizations: []int{}}
|
|
||||||
var p12 = sequenceParser{id: 12, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{}}
|
|
||||||
var p27 = charParser{id: 27, not: false, chars: []rune{59}, ranges: [][]rune{}}
|
|
||||||
p12.items = []parser{&p27}
|
|
||||||
var p129 = sequenceParser{id: 129, commit: 2, allChars: false, ranges: [][]int{{0, -1}, {1, 1}}, generalizations: []int{}}
|
|
||||||
p129.items = []parser{&p186, &p12}
|
|
||||||
p130.items = []parser{&p12, &p129, &p186, &p165}
|
|
||||||
var p33 = sequenceParser{id: 33, commit: 2, allChars: false, ranges: [][]int{{0, -1}, {1, 1}}, generalizations: []int{}}
|
|
||||||
p33.items = []parser{&p186, &p130}
|
|
||||||
p34.items = []parser{&p186, &p130, &p33}
|
|
||||||
p35.items = []parser{&p165, &p34}
|
|
||||||
var p72 = sequenceParser{id: 72, commit: 2, allChars: false, ranges: [][]int{{0, -1}, {1, 1}, {0, -1}}, generalizations: []int{}}
|
|
||||||
var p46 = sequenceParser{id: 46, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{}}
|
|
||||||
var p164 = charParser{id: 164, not: false, chars: []rune{59}, ranges: [][]rune{}}
|
|
||||||
p46.items = []parser{&p164}
|
|
||||||
var p71 = sequenceParser{id: 71, commit: 2, allChars: false, ranges: [][]int{{0, -1}, {1, 1}}, generalizations: []int{}}
|
|
||||||
p71.items = []parser{&p186, &p46}
|
|
||||||
p72.items = []parser{&p186, &p46, &p71}
|
|
||||||
p187.items = []parser{&p70, &p186, &p35, &p72}
|
|
||||||
p188.items = []parser{&p186, &p187, &p186}
|
|
||||||
var b188 = sequenceBuilder{id: 188, commit: 32, allChars: false, name: "syntax", ranges: [][]int{{0, -1}, {1, 1}, {0, -1}}}
|
|
||||||
var b186 = choiceBuilder{id: 186, commit: 2}
|
|
||||||
var b185 = choiceBuilder{id: 185, commit: 70}
|
|
||||||
var b171 = choiceBuilder{id: 171, commit: 66}
|
|
||||||
var b63 = sequenceBuilder{id: 63, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
|
||||||
var b28 = charBuilder{}
|
|
||||||
b63.items = []builder{&b28}
|
|
||||||
var b121 = sequenceBuilder{id: 121, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
|
||||||
var b17 = charBuilder{}
|
|
||||||
b121.items = []builder{&b17}
|
|
||||||
var b79 = sequenceBuilder{id: 79, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
|
||||||
var b53 = charBuilder{}
|
|
||||||
b79.items = []builder{&b53}
|
|
||||||
var b114 = sequenceBuilder{id: 114, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
|
||||||
var b96 = charBuilder{}
|
|
||||||
b114.items = []builder{&b96}
|
|
||||||
var b141 = sequenceBuilder{id: 141, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
|
||||||
var b9 = charBuilder{}
|
|
||||||
b141.items = []builder{&b9}
|
|
||||||
var b47 = sequenceBuilder{id: 47, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
|
||||||
var b87 = charBuilder{}
|
|
||||||
b47.items = []builder{&b87}
|
|
||||||
var b40 = sequenceBuilder{id: 40, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
|
||||||
var b18 = charBuilder{}
|
|
||||||
b40.items = []builder{&b18}
|
|
||||||
b171.options = []builder{&b63, &b121, &b79, &b114, &b141, &b47, &b40}
|
|
||||||
var b90 = sequenceBuilder{id: 90, commit: 72, allChars: false, name: "comment", ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {0, -1}}}
|
|
||||||
var b142 = choiceBuilder{id: 142, commit: 74}
|
|
||||||
var b80 = sequenceBuilder{id: 80, commit: 74, allChars: false, ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {0, -1}}}
|
|
||||||
var b41 = sequenceBuilder{id: 41, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}}}
|
|
||||||
var b65 = charBuilder{}
|
|
||||||
var b148 = charBuilder{}
|
|
||||||
b41.items = []builder{&b65, &b148}
|
|
||||||
var b55 = sequenceBuilder{id: 55, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
|
||||||
var b124 = charBuilder{}
|
|
||||||
b55.items = []builder{&b124}
|
|
||||||
b80.items = []builder{&b41, &b55}
|
|
||||||
var b48 = sequenceBuilder{id: 48, commit: 74, allChars: false, ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {1, 1}, {0, -1}, {1, 1}}}
|
|
||||||
var b97 = sequenceBuilder{id: 97, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}}}
|
|
||||||
var b64 = charBuilder{}
|
|
||||||
var b54 = charBuilder{}
|
|
||||||
b97.items = []builder{&b64, &b54}
|
|
||||||
var b89 = choiceBuilder{id: 89, commit: 10}
|
|
||||||
var b104 = sequenceBuilder{id: 104, commit: 10, allChars: false, ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}}}
|
|
||||||
var b29 = sequenceBuilder{id: 29, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
|
||||||
var b88 = charBuilder{}
|
|
||||||
b29.items = []builder{&b88}
|
|
||||||
var b122 = sequenceBuilder{id: 122, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
|
||||||
var b131 = charBuilder{}
|
|
||||||
b122.items = []builder{&b131}
|
|
||||||
b104.items = []builder{&b29, &b122}
|
|
||||||
var b159 = sequenceBuilder{id: 159, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
|
||||||
var b123 = charBuilder{}
|
|
||||||
b159.items = []builder{&b123}
|
|
||||||
b89.options = []builder{&b104, &b159}
|
|
||||||
var b19 = sequenceBuilder{id: 19, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}}}
|
|
||||||
var b153 = charBuilder{}
|
|
||||||
var b24 = charBuilder{}
|
|
||||||
b19.items = []builder{&b153, &b24}
|
|
||||||
b48.items = []builder{&b97, &b89, &b19}
|
|
||||||
b142.options = []builder{&b80, &b48}
|
|
||||||
var b3 = sequenceBuilder{id: 3, commit: 10, allChars: false, ranges: [][]int{{0, -1}, {0, 1}, {0, -1}, {1, 1}, {0, -1}, {0, 1}, {0, -1}, {1, 1}}}
|
|
||||||
var b160 = choiceBuilder{id: 160, commit: 74}
|
|
||||||
var b66 = sequenceBuilder{id: 66, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
|
||||||
var b109 = charBuilder{}
|
|
||||||
b66.items = []builder{&b109}
|
|
||||||
var b180 = sequenceBuilder{id: 180, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
|
||||||
var b30 = charBuilder{}
|
|
||||||
b180.items = []builder{&b30}
|
|
||||||
var b136 = sequenceBuilder{id: 136, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
|
||||||
var b125 = charBuilder{}
|
|
||||||
b136.items = []builder{&b125}
|
|
||||||
var b118 = sequenceBuilder{id: 118, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
|
||||||
var b31 = charBuilder{}
|
|
||||||
b118.items = []builder{&b31}
|
|
||||||
var b49 = sequenceBuilder{id: 49, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
|
||||||
var b73 = charBuilder{}
|
|
||||||
b49.items = []builder{&b73}
|
|
||||||
var b182 = sequenceBuilder{id: 182, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
|
||||||
var b181 = charBuilder{}
|
|
||||||
b182.items = []builder{&b181}
|
|
||||||
b160.options = []builder{&b66, &b180, &b136, &b118, &b49, &b182}
|
|
||||||
var b137 = sequenceBuilder{id: 137, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
|
||||||
var b105 = charBuilder{}
|
|
||||||
b137.items = []builder{&b105}
|
|
||||||
b3.items = []builder{&b160, &b137, &b160, &b142}
|
|
||||||
b90.items = []builder{&b142, &b3}
|
|
||||||
b185.options = []builder{&b171, &b90}
|
|
||||||
b186.options = []builder{&b185}
|
|
||||||
var b187 = sequenceBuilder{id: 187, commit: 66, allChars: false, ranges: [][]int{{0, 1}, {0, -1}, {0, 1}, {0, 1}}}
|
|
||||||
var b70 = sequenceBuilder{id: 70, commit: 2, allChars: false, ranges: [][]int{{1, 1}, {0, -1}}}
|
|
||||||
var b36 = sequenceBuilder{id: 36, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
|
||||||
var b140 = charBuilder{}
|
|
||||||
b36.items = []builder{&b140}
|
|
||||||
var b69 = sequenceBuilder{id: 69, commit: 2, allChars: false, ranges: [][]int{{0, -1}, {1, 1}}}
|
|
||||||
b69.items = []builder{&b186, &b36}
|
|
||||||
b70.items = []builder{&b36, &b69}
|
|
||||||
var b35 = sequenceBuilder{id: 35, commit: 66, allChars: false, ranges: [][]int{{1, 1}, {0, 1}}}
|
|
||||||
var b165 = sequenceBuilder{id: 165, commit: 64, allChars: false, name: "definition", ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {0, -1}, {1, 1}}}
|
|
||||||
var b95 = sequenceBuilder{id: 95, commit: 74, allChars: false, ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {0, -1}}}
|
|
||||||
var b42 = sequenceBuilder{id: 42, commit: 72, allChars: false, name: "symbol", ranges: [][]int{{1, -1}, {1, -1}}}
|
|
||||||
var b144 = sequenceBuilder{id: 144, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
|
||||||
var b169 = charBuilder{}
|
|
||||||
b144.items = []builder{&b169}
|
|
||||||
b42.items = []builder{&b144}
|
|
||||||
var b77 = sequenceBuilder{id: 77, commit: 10, allChars: false, ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}}}
|
|
||||||
var b155 = sequenceBuilder{id: 155, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
|
||||||
var b147 = charBuilder{}
|
|
||||||
b155.items = []builder{&b147}
|
|
||||||
var b52 = choiceBuilder{id: 52, commit: 66}
|
|
||||||
var b139 = sequenceBuilder{id: 139, commit: 72, allChars: true, name: "alias", ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}}}
|
|
||||||
var b15 = charBuilder{}
|
|
||||||
var b99 = charBuilder{}
|
|
||||||
var b174 = charBuilder{}
|
|
||||||
var b135 = charBuilder{}
|
|
||||||
var b16 = charBuilder{}
|
|
||||||
b139.items = []builder{&b15, &b99, &b174, &b135, &b16}
|
|
||||||
var b157 = sequenceBuilder{id: 157, commit: 72, allChars: true, name: "ws", ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}}}
|
|
||||||
var b43 = charBuilder{}
|
|
||||||
var b39 = charBuilder{}
|
|
||||||
b157.items = []builder{&b43, &b39}
|
|
||||||
var b116 = sequenceBuilder{id: 116, commit: 72, allChars: true, name: "nows", ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}}}
|
|
||||||
var b22 = charBuilder{}
|
|
||||||
var b145 = charBuilder{}
|
|
||||||
var b113 = charBuilder{}
|
|
||||||
var b1 = charBuilder{}
|
|
||||||
b116.items = []builder{&b22, &b145, &b113, &b1}
|
|
||||||
var b2 = sequenceBuilder{id: 2, commit: 72, allChars: true, name: "failpass", ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}}}
|
|
||||||
var b23 = charBuilder{}
|
|
||||||
var b82 = charBuilder{}
|
|
||||||
var b62 = charBuilder{}
|
|
||||||
var b59 = charBuilder{}
|
|
||||||
var b44 = charBuilder{}
|
|
||||||
var b100 = charBuilder{}
|
|
||||||
var b158 = charBuilder{}
|
|
||||||
var b103 = charBuilder{}
|
|
||||||
b2.items = []builder{&b23, &b82, &b62, &b59, &b44, &b100, &b158, &b103}
|
|
||||||
var b177 = sequenceBuilder{id: 177, commit: 72, allChars: true, name: "root", ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}}}
|
|
||||||
var b76 = charBuilder{}
|
|
||||||
var b83 = charBuilder{}
|
|
||||||
var b78 = charBuilder{}
|
|
||||||
var b45 = charBuilder{}
|
|
||||||
b177.items = []builder{&b76, &b83, &b78, &b45}
|
|
||||||
b52.options = []builder{&b139, &b157, &b116, &b2, &b177}
|
|
||||||
b77.items = []builder{&b155, &b52}
|
|
||||||
b95.items = []builder{&b42, &b77}
|
|
||||||
var b13 = sequenceBuilder{id: 13, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
|
||||||
var b117 = charBuilder{}
|
|
||||||
b13.items = []builder{&b117}
|
|
||||||
var b14 = choiceBuilder{id: 14, commit: 66}
|
|
||||||
var b168 = choiceBuilder{id: 168, commit: 66}
|
|
||||||
var b91 = sequenceBuilder{id: 91, commit: 72, allChars: true, name: "any-char", ranges: [][]int{{1, 1}, {1, 1}}}
|
|
||||||
var b106 = charBuilder{}
|
|
||||||
b91.items = []builder{&b106}
|
|
||||||
var b143 = sequenceBuilder{id: 143, commit: 72, allChars: false, name: "char-class", ranges: [][]int{{1, 1}, {0, 1}, {0, -1}, {1, 1}, {1, 1}, {0, 1}, {0, -1}, {1, 1}}}
|
|
||||||
var b111 = sequenceBuilder{id: 111, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
|
||||||
var b81 = charBuilder{}
|
|
||||||
b111.items = []builder{&b81}
|
|
||||||
var b50 = sequenceBuilder{id: 50, commit: 72, allChars: true, name: "class-not", ranges: [][]int{{1, 1}, {1, 1}}}
|
|
||||||
var b119 = charBuilder{}
|
|
||||||
b50.items = []builder{&b119}
|
|
||||||
var b149 = choiceBuilder{id: 149, commit: 10}
|
|
||||||
var b98 = choiceBuilder{id: 98, commit: 72, name: "class-char"}
|
|
||||||
var b166 = sequenceBuilder{id: 166, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
|
||||||
var b107 = charBuilder{}
|
|
||||||
b166.items = []builder{&b107}
|
|
||||||
var b110 = sequenceBuilder{id: 110, commit: 10, allChars: false, ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}}}
|
|
||||||
var b133 = sequenceBuilder{id: 133, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
|
||||||
var b132 = charBuilder{}
|
|
||||||
b133.items = []builder{&b132}
|
|
||||||
var b162 = sequenceBuilder{id: 162, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
|
||||||
var b161 = charBuilder{}
|
|
||||||
b162.items = []builder{&b161}
|
|
||||||
b110.items = []builder{&b133, &b162}
|
|
||||||
b98.options = []builder{&b166, &b110}
|
|
||||||
var b4 = sequenceBuilder{id: 4, commit: 72, allChars: false, name: "char-range", ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}}}
|
|
||||||
var b167 = sequenceBuilder{id: 167, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
|
||||||
var b175 = charBuilder{}
|
|
||||||
b167.items = []builder{&b175}
|
|
||||||
b4.items = []builder{&b98, &b167, &b98}
|
|
||||||
b149.options = []builder{&b98, &b4}
|
|
||||||
var b5 = sequenceBuilder{id: 5, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
|
||||||
var b183 = charBuilder{}
|
|
||||||
b5.items = []builder{&b183}
|
|
||||||
b143.items = []builder{&b111, &b50, &b149, &b5}
|
|
||||||
var b84 = sequenceBuilder{id: 84, commit: 72, allChars: false, name: "char-sequence", ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {1, 1}, {0, -1}, {1, 1}}}
|
|
||||||
var b101 = sequenceBuilder{id: 101, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
|
||||||
var b150 = charBuilder{}
|
|
||||||
b101.items = []builder{&b150}
|
|
||||||
var b172 = choiceBuilder{id: 172, commit: 72, name: "sequence-char"}
|
|
||||||
var b67 = sequenceBuilder{id: 67, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
|
||||||
var b74 = charBuilder{}
|
|
||||||
b67.items = []builder{&b74}
|
|
||||||
var b32 = sequenceBuilder{id: 32, commit: 10, allChars: false, ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}}}
|
|
||||||
var b108 = sequenceBuilder{id: 108, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
|
||||||
var b184 = charBuilder{}
|
|
||||||
b108.items = []builder{&b184}
|
|
||||||
var b10 = sequenceBuilder{id: 10, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
|
||||||
var b68 = charBuilder{}
|
|
||||||
b10.items = []builder{&b68}
|
|
||||||
b32.items = []builder{&b108, &b10}
|
|
||||||
b172.options = []builder{&b67, &b32}
|
|
||||||
var b25 = sequenceBuilder{id: 25, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
|
||||||
var b37 = charBuilder{}
|
|
||||||
b25.items = []builder{&b37}
|
|
||||||
b84.items = []builder{&b101, &b172, &b25}
|
|
||||||
b168.options = []builder{&b91, &b143, &b84}
|
|
||||||
var b21 = sequenceBuilder{id: 21, commit: 66, allChars: false, ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {0, -1}, {1, 1}}}
|
|
||||||
var b154 = sequenceBuilder{id: 154, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
|
||||||
var b56 = charBuilder{}
|
|
||||||
b154.items = []builder{&b56}
|
|
||||||
var b120 = sequenceBuilder{id: 120, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
|
||||||
var b20 = charBuilder{}
|
|
||||||
b120.items = []builder{&b20}
|
|
||||||
b21.items = []builder{&b154, &b186, &b14, &b186, &b120}
|
|
||||||
var b8 = sequenceBuilder{id: 8, commit: 64, allChars: false, name: "sequence", ranges: [][]int{{1, 1}, {0, -1}}}
|
|
||||||
var b115 = sequenceBuilder{id: 115, commit: 72, allChars: false, name: "item", ranges: [][]int{{1, 1}, {0, 1}, {1, 1}, {0, 1}}}
|
|
||||||
var b128 = choiceBuilder{id: 128, commit: 10}
|
|
||||||
b128.options = []builder{&b168, &b42, &b21}
|
|
||||||
var b179 = choiceBuilder{id: 179, commit: 66}
|
|
||||||
var b152 = sequenceBuilder{id: 152, commit: 64, allChars: false, name: "count-quantifier", ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {0, -1}, {1, 1}}}
|
|
||||||
var b170 = sequenceBuilder{id: 170, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
|
||||||
var b151 = charBuilder{}
|
|
||||||
b170.items = []builder{&b151}
|
|
||||||
var b127 = sequenceBuilder{id: 127, commit: 64, allChars: false, name: "count", ranges: [][]int{{1, 1}}}
|
|
||||||
var b51 = sequenceBuilder{id: 51, commit: 74, allChars: false, ranges: [][]int{{1, -1}, {1, -1}}}
|
|
||||||
var b176 = sequenceBuilder{id: 176, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
|
||||||
var b126 = charBuilder{}
|
|
||||||
b176.items = []builder{&b126}
|
|
||||||
b51.items = []builder{&b176}
|
|
||||||
b127.items = []builder{&b51}
|
|
||||||
var b6 = sequenceBuilder{id: 6, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
|
||||||
var b26 = charBuilder{}
|
|
||||||
b6.items = []builder{&b26}
|
|
||||||
b152.items = []builder{&b170, &b186, &b127, &b186, &b6}
|
|
||||||
var b92 = sequenceBuilder{id: 92, commit: 64, allChars: false, name: "range-quantifier", ranges: [][]int{{1, 1}, {0, -1}, {0, 1}, {0, -1}, {1, 1}, {0, -1}, {0, 1}, {0, -1}, {1, 1}}}
|
|
||||||
var b85 = sequenceBuilder{id: 85, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
|
||||||
var b75 = charBuilder{}
|
|
||||||
b85.items = []builder{&b75}
|
|
||||||
var b102 = sequenceBuilder{id: 102, commit: 64, allChars: false, name: "range-from", ranges: [][]int{{1, 1}}}
|
|
||||||
b102.items = []builder{&b51}
|
|
||||||
var b112 = sequenceBuilder{id: 112, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
|
||||||
var b86 = charBuilder{}
|
|
||||||
b112.items = []builder{&b86}
|
|
||||||
var b138 = sequenceBuilder{id: 138, commit: 64, allChars: false, name: "range-to", ranges: [][]int{{1, 1}}}
|
|
||||||
b138.items = []builder{&b51}
|
|
||||||
var b57 = sequenceBuilder{id: 57, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
|
||||||
var b58 = charBuilder{}
|
|
||||||
b57.items = []builder{&b58}
|
|
||||||
b92.items = []builder{&b85, &b186, &b102, &b186, &b112, &b186, &b138, &b186, &b57}
|
|
||||||
var b38 = sequenceBuilder{id: 38, commit: 72, allChars: true, name: "one-or-more", ranges: [][]int{{1, 1}, {1, 1}}}
|
|
||||||
var b163 = charBuilder{}
|
|
||||||
b38.items = []builder{&b163}
|
|
||||||
var b178 = sequenceBuilder{id: 178, commit: 72, allChars: true, name: "zero-or-more", ranges: [][]int{{1, 1}, {1, 1}}}
|
|
||||||
var b93 = charBuilder{}
|
|
||||||
b178.items = []builder{&b93}
|
|
||||||
var b156 = sequenceBuilder{id: 156, commit: 72, allChars: true, name: "zero-or-one", ranges: [][]int{{1, 1}, {1, 1}}}
|
|
||||||
var b146 = charBuilder{}
|
|
||||||
b156.items = []builder{&b146}
|
|
||||||
b179.options = []builder{&b152, &b92, &b38, &b178, &b156}
|
|
||||||
b115.items = []builder{&b128, &b179}
|
|
||||||
var b7 = sequenceBuilder{id: 7, commit: 2, allChars: false, ranges: [][]int{{0, -1}, {1, 1}}}
|
|
||||||
b7.items = []builder{&b186, &b115}
|
|
||||||
b8.items = []builder{&b115, &b7}
|
|
||||||
var b61 = sequenceBuilder{id: 61, commit: 64, allChars: false, name: "choice", ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {0, -1}}}
|
|
||||||
var b94 = choiceBuilder{id: 94, commit: 66}
|
|
||||||
b94.options = []builder{&b168, &b42, &b21, &b8}
|
|
||||||
var b11 = sequenceBuilder{id: 11, commit: 2, allChars: false, ranges: [][]int{{1, 1}, {0, -1}, {1, 1}}}
|
|
||||||
var b134 = sequenceBuilder{id: 134, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
|
||||||
var b173 = charBuilder{}
|
|
||||||
b134.items = []builder{&b173}
|
|
||||||
b11.items = []builder{&b134, &b186, &b94}
|
|
||||||
var b60 = sequenceBuilder{id: 60, commit: 2, allChars: false, ranges: [][]int{{0, -1}, {1, 1}}}
|
|
||||||
b60.items = []builder{&b186, &b11}
|
|
||||||
b61.items = []builder{&b94, &b186, &b11, &b60}
|
|
||||||
b14.options = []builder{&b168, &b42, &b21, &b8, &b61}
|
|
||||||
b165.items = []builder{&b95, &b186, &b13, &b186, &b14}
|
|
||||||
var b34 = sequenceBuilder{id: 34, commit: 2, allChars: false, ranges: [][]int{{0, -1}, {1, 1}, {0, -1}}}
|
|
||||||
var b130 = sequenceBuilder{id: 130, commit: 2, allChars: false, ranges: [][]int{{1, 1}, {0, -1}, {0, -1}, {1, 1}}}
|
|
||||||
var b12 = sequenceBuilder{id: 12, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
|
||||||
var b27 = charBuilder{}
|
|
||||||
b12.items = []builder{&b27}
|
|
||||||
var b129 = sequenceBuilder{id: 129, commit: 2, allChars: false, ranges: [][]int{{0, -1}, {1, 1}}}
|
|
||||||
b129.items = []builder{&b186, &b12}
|
|
||||||
b130.items = []builder{&b12, &b129, &b186, &b165}
|
|
||||||
var b33 = sequenceBuilder{id: 33, commit: 2, allChars: false, ranges: [][]int{{0, -1}, {1, 1}}}
|
|
||||||
b33.items = []builder{&b186, &b130}
|
|
||||||
b34.items = []builder{&b186, &b130, &b33}
|
|
||||||
b35.items = []builder{&b165, &b34}
|
|
||||||
var b72 = sequenceBuilder{id: 72, commit: 2, allChars: false, ranges: [][]int{{0, -1}, {1, 1}, {0, -1}}}
|
|
||||||
var b46 = sequenceBuilder{id: 46, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
|
||||||
var b164 = charBuilder{}
|
|
||||||
b46.items = []builder{&b164}
|
|
||||||
var b71 = sequenceBuilder{id: 71, commit: 2, allChars: false, ranges: [][]int{{0, -1}, {1, 1}}}
|
|
||||||
b71.items = []builder{&b186, &b46}
|
|
||||||
b72.items = []builder{&b186, &b46, &b71}
|
|
||||||
b187.items = []builder{&b70, &b186, &b35, &b72}
|
|
||||||
b188.items = []builder{&b186, &b187, &b186}
|
|
||||||
|
|
||||||
c := newContext(bufio.NewReader(r))
|
|
||||||
p188.parse(c)
|
|
||||||
if c.readErr != nil {
|
|
||||||
return nil, c.readErr
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := c.finalizeParse(&p188); err != nil {
|
|
||||||
if perr, ok := err.(*ParseError); ok {
|
|
||||||
perr.Input = "<input>"
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
c.offset = 0
|
|
||||||
c.results.resetPending()
|
|
||||||
|
|
||||||
n, _ := b188.build(c)
|
|
||||||
return n[0], nil
|
|
||||||
}
|
|
@ -7,11 +7,6 @@ import (
|
|||||||
"github.com/aryszka/treerack"
|
"github.com/aryszka/treerack"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
syntaxPath = "syntax.treerack"
|
|
||||||
outputPath = "parser.go"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
s := &treerack.Syntax{}
|
s := &treerack.Syntax{}
|
||||||
|
|
||||||
@ -19,7 +14,7 @@ func main() {
|
|||||||
log.Fatalln(err)
|
log.Fatalln(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := s.Generate(os.Stdout); err != nil {
|
if err := s.Generate(treerack.GeneratorOptions{PackageName: "self"}, os.Stdout); err != nil {
|
||||||
log.Fatalln(err)
|
log.Fatalln(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
102
scripts/createhead.go
Normal file
102
scripts/createhead.go
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"go/ast"
|
||||||
|
"go/parser"
|
||||||
|
"go/printer"
|
||||||
|
"go/token"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func concatGo(w io.Writer, r ...io.Reader) error {
|
||||||
|
var others []ast.Decl
|
||||||
|
imports := &ast.GenDecl{
|
||||||
|
Tok: token.IMPORT,
|
||||||
|
Lparen: 1,
|
||||||
|
Rparen: 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
importPaths := make(map[string]bool)
|
||||||
|
for i := range r {
|
||||||
|
f, err := parser.ParseFile(token.NewFileSet(), "", r[i], 0)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for j := range f.Decls {
|
||||||
|
d := f.Decls[j]
|
||||||
|
switch dd := d.(type) {
|
||||||
|
case *ast.GenDecl:
|
||||||
|
if dd.Tok != token.IMPORT {
|
||||||
|
others = append(others, d)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for k := range dd.Specs {
|
||||||
|
i := dd.Specs[k].(*ast.ImportSpec)
|
||||||
|
path := i.Path.Value
|
||||||
|
name := ""
|
||||||
|
if i.Name != nil {
|
||||||
|
name = i.Name.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
key := "(" + name + ")" + path
|
||||||
|
if importPaths[key] {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
importPaths[key] = true
|
||||||
|
imports.Specs = append(imports.Specs, i)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
others = append(others, d)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return printer.Fprint(w, token.NewFileSet(), &ast.File{
|
||||||
|
Name: &ast.Ident{Name: ""},
|
||||||
|
Decls: append([]ast.Decl{imports}, others...),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func removePackage(gO string) string {
|
||||||
|
// so we know that it's the first line
|
||||||
|
nl := strings.Index(gO, "\n")
|
||||||
|
return gO[nl+2:]
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var packageName string
|
||||||
|
flag.StringVar(&packageName, "package", "treerack", "package name of the generated code file")
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
var files []io.Reader
|
||||||
|
for _, fn := range flag.Args() {
|
||||||
|
f, err := os.Open(fn)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer f.Close()
|
||||||
|
files = append(files, f)
|
||||||
|
}
|
||||||
|
|
||||||
|
var headCode bytes.Buffer
|
||||||
|
if err := concatGo(&headCode, files...); err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
code := headCode.String()
|
||||||
|
code = removePackage(code)
|
||||||
|
quotedCode := strconv.Quote(code)
|
||||||
|
|
||||||
|
fmt.Printf("package %s\n\n// generated with scripts/createhead.go\nconst headCode=%s", packageName, quotedCode)
|
||||||
|
}
|
1345
self/self.go
Normal file
1345
self/self.go
Normal file
File diff suppressed because it is too large
Load Diff
374
sequence.go
374
sequence.go
@ -1,27 +1,5 @@
|
|||||||
package treerack
|
package treerack
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
type sequenceDefinition struct {
|
|
||||||
name string
|
|
||||||
id int
|
|
||||||
commit CommitType
|
|
||||||
originalItems []SequenceItem
|
|
||||||
items []SequenceItem
|
|
||||||
itemDefs []definition
|
|
||||||
ranges [][]int
|
|
||||||
generalizations []int
|
|
||||||
sbuilder *sequenceBuilder
|
|
||||||
sparser *sequenceParser
|
|
||||||
allChars bool
|
|
||||||
validated bool
|
|
||||||
initialized bool
|
|
||||||
}
|
|
||||||
|
|
||||||
type sequenceParser struct {
|
type sequenceParser struct {
|
||||||
name string
|
name string
|
||||||
id int
|
id int
|
||||||
@ -41,263 +19,6 @@ type sequenceBuilder struct {
|
|||||||
allChars bool
|
allChars bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func newSequence(name string, ct CommitType, items []SequenceItem) *sequenceDefinition {
|
|
||||||
original := make([]SequenceItem, len(items))
|
|
||||||
for i := range items {
|
|
||||||
original[i] = items[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
return &sequenceDefinition{
|
|
||||||
name: name,
|
|
||||||
commit: ct,
|
|
||||||
items: items,
|
|
||||||
originalItems: original,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *sequenceDefinition) nodeName() string { return d.name }
|
|
||||||
func (d *sequenceDefinition) setName(n string) { d.name = n }
|
|
||||||
func (d *sequenceDefinition) nodeID() int { return d.id }
|
|
||||||
func (d *sequenceDefinition) setID(id int) { d.id = id }
|
|
||||||
func (d *sequenceDefinition) commitType() CommitType { return d.commit }
|
|
||||||
func (d *sequenceDefinition) setCommitType(ct CommitType) { d.commit = ct }
|
|
||||||
|
|
||||||
func normalizeItemRange(item SequenceItem) SequenceItem {
|
|
||||||
if item.Min == 0 && item.Max == 0 {
|
|
||||||
item.Min, item.Max = 1, 1
|
|
||||||
return item
|
|
||||||
}
|
|
||||||
|
|
||||||
if item.Min <= 0 {
|
|
||||||
item.Min = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
if item.Max <= 0 {
|
|
||||||
item.Max = -1
|
|
||||||
}
|
|
||||||
|
|
||||||
return item
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *sequenceDefinition) initRanges() {
|
|
||||||
for i, item := range d.items {
|
|
||||||
item = normalizeItemRange(item)
|
|
||||||
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 {
|
|
||||||
if d.validated {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
d.validated = true
|
|
||||||
for i := range d.items {
|
|
||||||
ii, ok := r.definition(d.items[i].Name)
|
|
||||||
if !ok {
|
|
||||||
return parserNotFound(d.items[i].Name)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := ii.validate(r); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *sequenceDefinition) createBuilder() {
|
|
||||||
d.sbuilder = &sequenceBuilder{
|
|
||||||
name: d.name,
|
|
||||||
id: d.id,
|
|
||||||
commit: d.commit,
|
|
||||||
ranges: d.ranges,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *sequenceDefinition) initItems(r *registry) {
|
|
||||||
allChars := true
|
|
||||||
for _, item := range d.items {
|
|
||||||
def := r.definitions[item.Name]
|
|
||||||
d.itemDefs = append(d.itemDefs, def)
|
|
||||||
def.init(r)
|
|
||||||
d.sbuilder.items = append(d.sbuilder.items, def.builder())
|
|
||||||
if allChars {
|
|
||||||
if _, isChar := def.(*charParser); !isChar {
|
|
||||||
allChars = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
d.sbuilder.allChars = allChars
|
|
||||||
d.allChars = allChars
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *sequenceDefinition) init(r *registry) {
|
|
||||||
if d.initialized {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
d.initialized = true
|
|
||||||
d.initRanges()
|
|
||||||
d.createBuilder()
|
|
||||||
d.initItems(r)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *sequenceDefinition) addGeneralization(g int) {
|
|
||||||
if intsContain(d.generalizations, g) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
d.generalizations = append(d.generalizations, g)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *sequenceDefinition) createParser() {
|
|
||||||
d.sparser = &sequenceParser{
|
|
||||||
name: d.name,
|
|
||||||
id: d.id,
|
|
||||||
commit: d.commit,
|
|
||||||
generalizations: d.generalizations,
|
|
||||||
allChars: d.allChars,
|
|
||||||
ranges: d.ranges,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *sequenceDefinition) createItemParsers() {
|
|
||||||
for _, item := range d.itemDefs {
|
|
||||||
pi := item.parser()
|
|
||||||
d.sparser.items = append(d.sparser.items, pi)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *sequenceDefinition) parser() parser {
|
|
||||||
if d.sparser != nil {
|
|
||||||
return d.sparser
|
|
||||||
}
|
|
||||||
|
|
||||||
d.createParser()
|
|
||||||
d.createItemParsers()
|
|
||||||
return d.sparser
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *sequenceDefinition) builder() builder { return d.sbuilder }
|
|
||||||
|
|
||||||
func (d *sequenceDefinition) isCharSequence(r *registry) bool {
|
|
||||||
for i := range d.originalItems {
|
|
||||||
item := normalizeItemRange(d.originalItems[i])
|
|
||||||
if item.Min != 1 || item.Max != 1 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
itemDef, _ := r.definition(d.originalItems[i].Name)
|
|
||||||
c, ok := itemDef.(*charParser)
|
|
||||||
if !ok || !c.isSingleChar() {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *sequenceDefinition) format(r *registry, f formatFlags) string {
|
|
||||||
if d.isCharSequence(r) {
|
|
||||||
if len(d.originalItems) == 1 {
|
|
||||||
itemDef, _ := r.definition(d.originalItems[0].Name)
|
|
||||||
c, _ := itemDef.(*charParser)
|
|
||||||
return c.format(r, f)
|
|
||||||
}
|
|
||||||
|
|
||||||
var chars []rune
|
|
||||||
for i := range d.originalItems {
|
|
||||||
itemDef, _ := r.definition(d.originalItems[i].Name)
|
|
||||||
c, _ := itemDef.(*charParser)
|
|
||||||
chars = append(chars, c.chars[0])
|
|
||||||
}
|
|
||||||
|
|
||||||
chars = escape(charClassEscape, []rune(charClassBanned), chars)
|
|
||||||
return string(append([]rune{'"'}, append(chars, '"')...))
|
|
||||||
}
|
|
||||||
|
|
||||||
var chars []rune
|
|
||||||
for i := range d.originalItems {
|
|
||||||
if len(chars) > 0 {
|
|
||||||
chars = append(chars, ' ')
|
|
||||||
}
|
|
||||||
|
|
||||||
item := normalizeItemRange(d.originalItems[i])
|
|
||||||
needsQuantifier := item.Min != 1 || item.Max != 1
|
|
||||||
|
|
||||||
itemDef, _ := r.definition(item.Name)
|
|
||||||
isSymbol := itemDef.commitType()&userDefined != 0
|
|
||||||
|
|
||||||
ch, isChoice := itemDef.(*choiceDefinition)
|
|
||||||
isChoiceOfMultiple := isChoice && len(ch.options) > 1
|
|
||||||
|
|
||||||
seq, isSequence := itemDef.(*sequenceDefinition)
|
|
||||||
isSequenceOfMultiple := isSequence && len(seq.originalItems) > 1 && !seq.isCharSequence(r)
|
|
||||||
|
|
||||||
needsGrouping := isChoiceOfMultiple || isSequenceOfMultiple
|
|
||||||
|
|
||||||
if isSymbol {
|
|
||||||
chars = append(chars, []rune(itemDef.nodeName())...)
|
|
||||||
} else {
|
|
||||||
if needsGrouping {
|
|
||||||
chars = append(chars, '(')
|
|
||||||
}
|
|
||||||
|
|
||||||
chars = append(chars, []rune(itemDef.format(r, f))...)
|
|
||||||
|
|
||||||
if needsGrouping {
|
|
||||||
chars = append(chars, ')')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !needsQuantifier {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if item.Min == 0 && item.Max == 1 {
|
|
||||||
chars = append(chars, '?')
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if item.Min == 0 && item.Max < 0 {
|
|
||||||
chars = append(chars, '*')
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if item.Min == 1 && item.Max < 0 {
|
|
||||||
chars = append(chars, '+')
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
chars = append(chars, '{')
|
|
||||||
|
|
||||||
if item.Min == item.Max {
|
|
||||||
chars = append(chars, []rune(strconv.Itoa(item.Min))...)
|
|
||||||
} else {
|
|
||||||
if item.Min > 0 {
|
|
||||||
chars = append(chars, []rune(strconv.Itoa(item.Min))...)
|
|
||||||
}
|
|
||||||
|
|
||||||
chars = append(chars, ',')
|
|
||||||
|
|
||||||
if item.Max >= 0 {
|
|
||||||
chars = append(chars, []rune(strconv.Itoa(item.Max))...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
chars = append(chars, '}')
|
|
||||||
}
|
|
||||||
|
|
||||||
return string(chars)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *sequenceParser) nodeName() string { return p.name }
|
func (p *sequenceParser) nodeName() string { return p.name }
|
||||||
func (p *sequenceParser) nodeID() int { return p.id }
|
func (p *sequenceParser) nodeID() int { return p.id }
|
||||||
func (p *sequenceParser) commitType() CommitType { return p.commit }
|
func (p *sequenceParser) commitType() CommitType { return p.commit }
|
||||||
@ -376,57 +97,6 @@ func (p *sequenceParser) parse(c *context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *sequenceParser) generate(w io.Writer, done map[string]bool) error {
|
|
||||||
if done[p.name] {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
done[p.name] = true
|
|
||||||
|
|
||||||
var err error
|
|
||||||
fprintf := func(f string, args ...interface{}) {
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = fmt.Fprintf(w, f, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf("var p%d = sequenceParser{", p.id)
|
|
||||||
fprintf("id: %d, commit: %d, allChars: %t,", p.id, p.commit, p.allChars)
|
|
||||||
if p.commit&userDefined != 0 {
|
|
||||||
fprintf("name: \"%s\",", p.name)
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf("ranges: [][]int{")
|
|
||||||
for i := range p.ranges {
|
|
||||||
fprintf("{%d, %d},", p.ranges[i][0], p.ranges[i][1])
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf("},")
|
|
||||||
|
|
||||||
fprintf("generalizations: []int{")
|
|
||||||
for i := range p.generalizations {
|
|
||||||
fprintf("%d,", p.generalizations[i])
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf("}};")
|
|
||||||
|
|
||||||
for i := range p.items {
|
|
||||||
if err := p.items[i].generate(w, done); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf("p%d.items = []parser{", p.id)
|
|
||||||
for i := range p.items {
|
|
||||||
fprintf("&p%d,", p.items[i].nodeID())
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf("};")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *sequenceBuilder) nodeName() string { return b.name }
|
func (b *sequenceBuilder) nodeName() string { return b.name }
|
||||||
func (b *sequenceBuilder) nodeID() int { return b.id }
|
func (b *sequenceBuilder) nodeID() int { return b.id }
|
||||||
|
|
||||||
@ -514,47 +184,3 @@ func (b *sequenceBuilder) build(c *context) ([]*Node, bool) {
|
|||||||
tokens: c.tokens,
|
tokens: c.tokens,
|
||||||
}}, true
|
}}, true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *sequenceBuilder) generate(w io.Writer, done map[string]bool) error {
|
|
||||||
if done[b.name] {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
done[b.name] = true
|
|
||||||
|
|
||||||
var err error
|
|
||||||
fprintf := func(f string, args ...interface{}) {
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = fmt.Fprintf(w, f, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf("var b%d = sequenceBuilder{", b.id)
|
|
||||||
fprintf("id: %d, commit: %d, allChars: %t,", b.id, b.commit, b.allChars)
|
|
||||||
if b.commit&Alias == 0 {
|
|
||||||
fprintf("name: \"%s\",", b.name)
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf("ranges: [][]int{")
|
|
||||||
for i := range b.ranges {
|
|
||||||
fprintf("{%d, %d},", b.ranges[i][0], b.ranges[i][1])
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf("}};")
|
|
||||||
|
|
||||||
for i := range b.items {
|
|
||||||
if err := b.items[i].generate(w, done); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf("b%d.items = []builder{", b.id)
|
|
||||||
for i := range b.items {
|
|
||||||
fprintf("&b%d,", b.items[i].nodeID())
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf("};")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
375
sequencedefine.go
Normal file
375
sequencedefine.go
Normal file
@ -0,0 +1,375 @@
|
|||||||
|
package treerack
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
type sequenceDefinition struct {
|
||||||
|
name string
|
||||||
|
id int
|
||||||
|
commit CommitType
|
||||||
|
originalItems []SequenceItem
|
||||||
|
items []SequenceItem
|
||||||
|
itemDefs []definition
|
||||||
|
ranges [][]int
|
||||||
|
generalizations []int
|
||||||
|
sbuilder *sequenceBuilder
|
||||||
|
sparser *sequenceParser
|
||||||
|
allChars bool
|
||||||
|
validated bool
|
||||||
|
initialized bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func newSequence(name string, ct CommitType, items []SequenceItem) *sequenceDefinition {
|
||||||
|
original := make([]SequenceItem, len(items))
|
||||||
|
for i := range items {
|
||||||
|
original[i] = items[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
return &sequenceDefinition{
|
||||||
|
name: name,
|
||||||
|
commit: ct,
|
||||||
|
items: items,
|
||||||
|
originalItems: original,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *sequenceDefinition) nodeName() string { return d.name }
|
||||||
|
func (d *sequenceDefinition) setName(n string) { d.name = n }
|
||||||
|
func (d *sequenceDefinition) nodeID() int { return d.id }
|
||||||
|
func (d *sequenceDefinition) setID(id int) { d.id = id }
|
||||||
|
func (d *sequenceDefinition) commitType() CommitType { return d.commit }
|
||||||
|
func (d *sequenceDefinition) setCommitType(ct CommitType) { d.commit = ct }
|
||||||
|
|
||||||
|
func normalizeItemRange(item SequenceItem) SequenceItem {
|
||||||
|
if item.Min == 0 && item.Max == 0 {
|
||||||
|
item.Min, item.Max = 1, 1
|
||||||
|
return item
|
||||||
|
}
|
||||||
|
|
||||||
|
if item.Min <= 0 {
|
||||||
|
item.Min = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if item.Max <= 0 {
|
||||||
|
item.Max = -1
|
||||||
|
}
|
||||||
|
|
||||||
|
return item
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *sequenceDefinition) initRanges() {
|
||||||
|
for i, item := range d.items {
|
||||||
|
item = normalizeItemRange(item)
|
||||||
|
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 {
|
||||||
|
if d.validated {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
d.validated = true
|
||||||
|
for i := range d.items {
|
||||||
|
ii, ok := r.definition(d.items[i].Name)
|
||||||
|
if !ok {
|
||||||
|
return parserNotFound(d.items[i].Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := ii.validate(r); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *sequenceDefinition) createBuilder() {
|
||||||
|
d.sbuilder = &sequenceBuilder{
|
||||||
|
name: d.name,
|
||||||
|
id: d.id,
|
||||||
|
commit: d.commit,
|
||||||
|
ranges: d.ranges,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *sequenceDefinition) initItems(r *registry) {
|
||||||
|
allChars := true
|
||||||
|
for _, item := range d.items {
|
||||||
|
def := r.definitions[item.Name]
|
||||||
|
d.itemDefs = append(d.itemDefs, def)
|
||||||
|
def.init(r)
|
||||||
|
d.sbuilder.items = append(d.sbuilder.items, def.builder())
|
||||||
|
if allChars {
|
||||||
|
if _, isChar := def.(*charParser); !isChar {
|
||||||
|
allChars = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
d.sbuilder.allChars = allChars
|
||||||
|
d.allChars = allChars
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *sequenceDefinition) init(r *registry) {
|
||||||
|
if d.initialized {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
d.initialized = true
|
||||||
|
d.initRanges()
|
||||||
|
d.createBuilder()
|
||||||
|
d.initItems(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *sequenceDefinition) addGeneralization(g int) {
|
||||||
|
if intsContain(d.generalizations, g) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
d.generalizations = append(d.generalizations, g)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *sequenceDefinition) createParser() {
|
||||||
|
d.sparser = &sequenceParser{
|
||||||
|
name: d.name,
|
||||||
|
id: d.id,
|
||||||
|
commit: d.commit,
|
||||||
|
generalizations: d.generalizations,
|
||||||
|
allChars: d.allChars,
|
||||||
|
ranges: d.ranges,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *sequenceDefinition) createItemParsers() {
|
||||||
|
for _, item := range d.itemDefs {
|
||||||
|
pi := item.parser()
|
||||||
|
d.sparser.items = append(d.sparser.items, pi)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *sequenceDefinition) parser() parser {
|
||||||
|
if d.sparser != nil {
|
||||||
|
return d.sparser
|
||||||
|
}
|
||||||
|
|
||||||
|
d.createParser()
|
||||||
|
d.createItemParsers()
|
||||||
|
return d.sparser
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *sequenceDefinition) builder() builder { return d.sbuilder }
|
||||||
|
|
||||||
|
func (d *sequenceDefinition) isCharSequence(r *registry) bool {
|
||||||
|
for i := range d.originalItems {
|
||||||
|
item := normalizeItemRange(d.originalItems[i])
|
||||||
|
if item.Min != 1 || item.Max != 1 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
itemDef, _ := r.definition(d.originalItems[i].Name)
|
||||||
|
c, ok := itemDef.(*charParser)
|
||||||
|
if !ok || !c.isSingleChar() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *sequenceDefinition) format(r *registry, f formatFlags) string {
|
||||||
|
if d.isCharSequence(r) {
|
||||||
|
if len(d.originalItems) == 1 {
|
||||||
|
itemDef, _ := r.definition(d.originalItems[0].Name)
|
||||||
|
c, _ := itemDef.(*charParser)
|
||||||
|
return c.format(r, f)
|
||||||
|
}
|
||||||
|
|
||||||
|
var chars []rune
|
||||||
|
for i := range d.originalItems {
|
||||||
|
itemDef, _ := r.definition(d.originalItems[i].Name)
|
||||||
|
c, _ := itemDef.(*charParser)
|
||||||
|
chars = append(chars, c.chars[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
chars = escape(charClassEscape, []rune(charClassBanned), chars)
|
||||||
|
return string(append([]rune{'"'}, append(chars, '"')...))
|
||||||
|
}
|
||||||
|
|
||||||
|
var chars []rune
|
||||||
|
for i := range d.originalItems {
|
||||||
|
if len(chars) > 0 {
|
||||||
|
chars = append(chars, ' ')
|
||||||
|
}
|
||||||
|
|
||||||
|
item := normalizeItemRange(d.originalItems[i])
|
||||||
|
needsQuantifier := item.Min != 1 || item.Max != 1
|
||||||
|
|
||||||
|
itemDef, _ := r.definition(item.Name)
|
||||||
|
isSymbol := itemDef.commitType()&userDefined != 0
|
||||||
|
|
||||||
|
ch, isChoice := itemDef.(*choiceDefinition)
|
||||||
|
isChoiceOfMultiple := isChoice && len(ch.options) > 1
|
||||||
|
|
||||||
|
seq, isSequence := itemDef.(*sequenceDefinition)
|
||||||
|
isSequenceOfMultiple := isSequence && len(seq.originalItems) > 1 && !seq.isCharSequence(r)
|
||||||
|
|
||||||
|
needsGrouping := isChoiceOfMultiple || isSequenceOfMultiple
|
||||||
|
|
||||||
|
if isSymbol {
|
||||||
|
chars = append(chars, []rune(itemDef.nodeName())...)
|
||||||
|
} else {
|
||||||
|
if needsGrouping {
|
||||||
|
chars = append(chars, '(')
|
||||||
|
}
|
||||||
|
|
||||||
|
chars = append(chars, []rune(itemDef.format(r, f))...)
|
||||||
|
|
||||||
|
if needsGrouping {
|
||||||
|
chars = append(chars, ')')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !needsQuantifier {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if item.Min == 0 && item.Max == 1 {
|
||||||
|
chars = append(chars, '?')
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if item.Min == 0 && item.Max < 0 {
|
||||||
|
chars = append(chars, '*')
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if item.Min == 1 && item.Max < 0 {
|
||||||
|
chars = append(chars, '+')
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
chars = append(chars, '{')
|
||||||
|
|
||||||
|
if item.Min == item.Max {
|
||||||
|
chars = append(chars, []rune(strconv.Itoa(item.Min))...)
|
||||||
|
} else {
|
||||||
|
if item.Min > 0 {
|
||||||
|
chars = append(chars, []rune(strconv.Itoa(item.Min))...)
|
||||||
|
}
|
||||||
|
|
||||||
|
chars = append(chars, ',')
|
||||||
|
|
||||||
|
if item.Max >= 0 {
|
||||||
|
chars = append(chars, []rune(strconv.Itoa(item.Max))...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
chars = append(chars, '}')
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(chars)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *sequenceParser) generate(w io.Writer, done map[string]bool) error {
|
||||||
|
if done[p.name] {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
done[p.name] = true
|
||||||
|
|
||||||
|
var err error
|
||||||
|
fprintf := func(f string, args ...interface{}) {
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = fmt.Fprintf(w, f, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf("var p%d = sequenceParser{", p.id)
|
||||||
|
fprintf("id: %d, commit: %d, allChars: %t,", p.id, p.commit, p.allChars)
|
||||||
|
if p.commit&userDefined != 0 {
|
||||||
|
fprintf("name: \"%s\",", p.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf("ranges: [][]int{")
|
||||||
|
for i := range p.ranges {
|
||||||
|
fprintf("{%d, %d},", p.ranges[i][0], p.ranges[i][1])
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf("},")
|
||||||
|
|
||||||
|
fprintf("generalizations: []int{")
|
||||||
|
for i := range p.generalizations {
|
||||||
|
fprintf("%d,", p.generalizations[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf("}};")
|
||||||
|
|
||||||
|
for i := range p.items {
|
||||||
|
if err := p.items[i].(generator).generate(w, done); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf("p%d.items = []parser{", p.id)
|
||||||
|
for i := range p.items {
|
||||||
|
fprintf("&p%d,", p.items[i].nodeID())
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf("};")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *sequenceBuilder) generate(w io.Writer, done map[string]bool) error {
|
||||||
|
if done[b.name] {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
done[b.name] = true
|
||||||
|
|
||||||
|
var err error
|
||||||
|
fprintf := func(f string, args ...interface{}) {
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = fmt.Fprintf(w, f, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf("var b%d = sequenceBuilder{", b.id)
|
||||||
|
fprintf("id: %d, commit: %d, allChars: %t,", b.id, b.commit, b.allChars)
|
||||||
|
if b.commit&Alias == 0 {
|
||||||
|
fprintf("name: \"%s\",", b.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf("ranges: [][]int{")
|
||||||
|
for i := range b.ranges {
|
||||||
|
fprintf("{%d, %d},", b.ranges[i][0], b.ranges[i][1])
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf("}};")
|
||||||
|
|
||||||
|
for i := range b.items {
|
||||||
|
if err := b.items[i].(generator).generate(w, done); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf("b%d.items = []builder{", b.id)
|
||||||
|
for i := range b.items {
|
||||||
|
fprintf("&b%d,", b.items[i].nodeID())
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf("};")
|
||||||
|
return err
|
||||||
|
}
|
211
syntax.go
211
syntax.go
@ -1,31 +1,11 @@
|
|||||||
package treerack
|
package treerack
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
)
|
|
||||||
|
|
||||||
type CommitType int
|
"github.com/aryszka/treerack/self"
|
||||||
|
|
||||||
const (
|
|
||||||
None CommitType = 0
|
|
||||||
Alias CommitType = 1 << iota
|
|
||||||
Whitespace
|
|
||||||
NoWhitespace
|
|
||||||
FailPass
|
|
||||||
Root
|
|
||||||
|
|
||||||
userDefined
|
|
||||||
)
|
|
||||||
|
|
||||||
type formatFlags int
|
|
||||||
|
|
||||||
const (
|
|
||||||
formatNone formatFlags = 0
|
|
||||||
formatPretty formatFlags = 1 << iota
|
|
||||||
formatIncludeComments
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// if min=0&&max=0, it means min=1,max=1
|
// if min=0&&max=0, it means min=1,max=1
|
||||||
@ -36,33 +16,6 @@ type SequenceItem struct {
|
|||||||
Min, Max int
|
Min, Max int
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParseError is returned when the input text doesn't match
|
|
||||||
// the used syntax during parsing.
|
|
||||||
type ParseError struct {
|
|
||||||
|
|
||||||
// Input is the name of the input file or <input> if not
|
|
||||||
// available.
|
|
||||||
Input string
|
|
||||||
|
|
||||||
// Offset is the index of the right-most failing
|
|
||||||
// token in the input text.
|
|
||||||
Offset int
|
|
||||||
|
|
||||||
// Line tells the line index of the right-most failing
|
|
||||||
// token in the input text.
|
|
||||||
//
|
|
||||||
// It is zero-based, and for error reporting, it is
|
|
||||||
// recommended to increment it by one.
|
|
||||||
Line int
|
|
||||||
|
|
||||||
// Column tells the column index of the right-most failing
|
|
||||||
// token in the input text.
|
|
||||||
Column int
|
|
||||||
|
|
||||||
// Definition tells the right-most unmatched parser definition.
|
|
||||||
Definition string
|
|
||||||
}
|
|
||||||
|
|
||||||
type Syntax struct {
|
type Syntax struct {
|
||||||
registry *registry
|
registry *registry
|
||||||
initialized bool
|
initialized bool
|
||||||
@ -73,6 +26,15 @@ type Syntax struct {
|
|||||||
builder builder
|
builder builder
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type GeneratorOptions struct {
|
||||||
|
PackageName string
|
||||||
|
}
|
||||||
|
|
||||||
|
// applied in a non-type-checked way
|
||||||
|
type generator interface {
|
||||||
|
generate(io.Writer, map[string]bool) error
|
||||||
|
}
|
||||||
|
|
||||||
type definition interface {
|
type definition interface {
|
||||||
nodeName() string
|
nodeName() string
|
||||||
setName(string)
|
setName(string)
|
||||||
@ -89,34 +51,14 @@ type definition interface {
|
|||||||
format(*registry, formatFlags) string
|
format(*registry, formatFlags) string
|
||||||
}
|
}
|
||||||
|
|
||||||
type parser interface {
|
|
||||||
nodeName() string
|
|
||||||
nodeID() int
|
|
||||||
commitType() CommitType
|
|
||||||
parse(*context)
|
|
||||||
generate(io.Writer, map[string]bool) error
|
|
||||||
}
|
|
||||||
|
|
||||||
type builder interface {
|
|
||||||
nodeName() string
|
|
||||||
nodeID() int
|
|
||||||
build(*context) ([]*Node, bool)
|
|
||||||
generate(io.Writer, map[string]bool) error
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ErrSyntaxInitialized = errors.New("syntax initialized")
|
ErrSyntaxInitialized = errors.New("syntax initialized")
|
||||||
ErrInitFailed = errors.New("init failed")
|
ErrInitFailed = errors.New("init failed")
|
||||||
ErrNoParsersDefined = errors.New("no parsers defined")
|
ErrNoParsersDefined = errors.New("no parsers defined")
|
||||||
ErrInvalidInput = errors.New("invalid input")
|
|
||||||
ErrInvalidUnicodeCharacter = errors.New("invalid unicode character")
|
|
||||||
ErrInvalidEscapeCharacter = errors.New("invalid escape character")
|
ErrInvalidEscapeCharacter = errors.New("invalid escape character")
|
||||||
ErrUnexpectedCharacter = errors.New("unexpected character")
|
|
||||||
ErrInvalidSyntax = errors.New("invalid syntax")
|
|
||||||
ErrRootAlias = errors.New("root node cannot be an alias")
|
ErrRootAlias = errors.New("root node cannot be an alias")
|
||||||
ErrRootWhitespace = errors.New("root node cannot be a whitespace")
|
ErrRootWhitespace = errors.New("root node cannot be a whitespace")
|
||||||
ErrRootFailPass = errors.New("root node cannot pass failing definition")
|
ErrRootFailPass = errors.New("root node cannot pass failing definition")
|
||||||
ErrNotImplemented = errors.New("not implemented")
|
|
||||||
ErrMultipleRoots = errors.New("multiple roots")
|
ErrMultipleRoots = errors.New("multiple roots")
|
||||||
ErrInvalidSymbolName = errors.New("invalid symbol name")
|
ErrInvalidSymbolName = errors.New("invalid symbol name")
|
||||||
)
|
)
|
||||||
@ -215,6 +157,10 @@ func isValidSymbol(n string) bool {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// func (pe *ParseError) Verbose() string {
|
||||||
|
// return ""
|
||||||
|
// }
|
||||||
|
|
||||||
func intsContain(is []int, i int) bool {
|
func intsContain(is []int, i int) bool {
|
||||||
for _, ii := range is {
|
for _, ii := range is {
|
||||||
if ii == i {
|
if ii == i {
|
||||||
@ -225,20 +171,6 @@ func intsContain(is []int, i int) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pe *ParseError) Error() string {
|
|
||||||
return fmt.Sprintf(
|
|
||||||
"%s:%d:%d:parse failed, parsing: %s",
|
|
||||||
pe.Input,
|
|
||||||
pe.Line+1,
|
|
||||||
pe.Column+1,
|
|
||||||
pe.Definition,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// func (pe *ParseError) Verbose() string {
|
|
||||||
// return ""
|
|
||||||
// }
|
|
||||||
|
|
||||||
func (s *Syntax) applyRoot(d definition) error {
|
func (s *Syntax) applyRoot(d definition) error {
|
||||||
explicitRoot := d.commitType()&Root != 0
|
explicitRoot := d.commitType()&Root != 0
|
||||||
if explicitRoot && s.explicitRoot {
|
if explicitRoot && s.explicitRoot {
|
||||||
@ -369,16 +301,12 @@ func (s *Syntax) ReadSyntax(r io.Reader) error {
|
|||||||
return ErrSyntaxInitialized
|
return ErrSyntaxInitialized
|
||||||
}
|
}
|
||||||
|
|
||||||
b, err := bootSyntax()
|
sn, err := self.Parse(r)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
n, err := b.Parse(r)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
n := mapSelfNode(sn)
|
||||||
return define(s, n)
|
return define(s, n)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -430,59 +358,68 @@ func (s *Syntax) Init() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Syntax) Generate(w io.Writer) error {
|
func (s *Syntax) Generate(o GeneratorOptions, w io.Writer) error {
|
||||||
if err := s.Init(); err != nil {
|
if err := s.Init(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := fmt.Fprint(w, `
|
if o.PackageName == "" {
|
||||||
package treerack
|
o.PackageName = "main"
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"io"
|
|
||||||
)
|
|
||||||
|
|
||||||
func parsegen(r io.Reader) (*Node, error) {
|
|
||||||
`); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
fprintf := func(f string, args ...interface{}) {
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = fmt.Fprintf(w, f, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
fprint := func(args ...interface{}) {
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = fmt.Fprint(w, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintln := func() {
|
||||||
|
fprint("\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
fprint(gendoc)
|
||||||
|
fprintln()
|
||||||
|
fprintln()
|
||||||
|
|
||||||
|
fprintf("package %s", o.PackageName)
|
||||||
|
fprintln()
|
||||||
|
fprintln()
|
||||||
|
|
||||||
|
// generate headCode with scripts/createhead.go
|
||||||
|
fprint(headCode)
|
||||||
|
fprintln()
|
||||||
|
fprintln()
|
||||||
|
|
||||||
|
fprint(`func Parse(r io.Reader) (*Node, error) {`)
|
||||||
|
fprintln()
|
||||||
|
|
||||||
done := make(map[string]bool)
|
done := make(map[string]bool)
|
||||||
if err := s.parser.generate(w, done); err != nil {
|
if err := s.parser.(generator).generate(w, done); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
done = make(map[string]bool)
|
done = make(map[string]bool)
|
||||||
if err := s.builder.generate(w, done); err != nil {
|
if err := s.builder.(generator).generate(w, done); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := fmt.Fprintf(w, `
|
fprintln()
|
||||||
|
fprintln()
|
||||||
c := newContext(bufio.NewReader(r))
|
fprintf(`return parse(r, &p%d, &b%d)`, s.parser.nodeID(), s.builder.nodeID())
|
||||||
p%d.parse(c)
|
fprintln()
|
||||||
if c.readErr != nil {
|
fprint(`}`)
|
||||||
return nil, c.readErr
|
fprintln()
|
||||||
}
|
|
||||||
|
|
||||||
if err := c.finalizeParse(&p%d); err != nil {
|
|
||||||
if perr, ok := err.(*ParseError); ok {
|
|
||||||
perr.Input = "<input>"
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
c.offset = 0
|
|
||||||
c.results.resetPending()
|
|
||||||
|
|
||||||
n, _ := b%d.build(c)
|
|
||||||
return n[0], nil
|
|
||||||
}
|
|
||||||
`, s.parser.nodeID(), s.parser.nodeID(), s.builder.nodeID()); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -492,23 +429,5 @@ func (s *Syntax) Parse(r io.Reader) (*Node, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
c := newContext(bufio.NewReader(r))
|
return parse(r, s.parser, s.builder)
|
||||||
s.parser.parse(c)
|
|
||||||
if c.readErr != nil {
|
|
||||||
return nil, c.readErr
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := c.finalizeParse(s.parser); err != nil {
|
|
||||||
if perr, ok := err.(*ParseError); ok {
|
|
||||||
perr.Input = "<input>"
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
c.offset = 0
|
|
||||||
c.results.resetPending()
|
|
||||||
|
|
||||||
n, _ := s.builder.build(c)
|
|
||||||
return n[0], nil
|
|
||||||
}
|
}
|
||||||
|
@ -376,7 +376,7 @@ func TestGenerateSyntax(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := s.Generate(bytes.NewBuffer(nil)); err == nil {
|
if err := s.Generate(GeneratorOptions{}, bytes.NewBuffer(nil)); err == nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -388,7 +388,7 @@ func TestGenerateSyntax(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := s.Generate(bytes.NewBuffer(nil)); err == nil {
|
if err := s.Generate(GeneratorOptions{}, bytes.NewBuffer(nil)); err == nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
103
syntaxhead.go
Normal file
103
syntaxhead.go
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
package treerack
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CommitType int
|
||||||
|
|
||||||
|
const (
|
||||||
|
None CommitType = 0
|
||||||
|
Alias CommitType = 1 << iota
|
||||||
|
Whitespace
|
||||||
|
NoWhitespace
|
||||||
|
FailPass
|
||||||
|
Root
|
||||||
|
|
||||||
|
userDefined
|
||||||
|
)
|
||||||
|
|
||||||
|
type formatFlags int
|
||||||
|
|
||||||
|
const (
|
||||||
|
formatNone formatFlags = 0
|
||||||
|
formatPretty formatFlags = 1 << iota
|
||||||
|
formatIncludeComments
|
||||||
|
)
|
||||||
|
|
||||||
|
// ParseError is returned when the input text doesn't match
|
||||||
|
// the used syntax during parsing.
|
||||||
|
type ParseError struct {
|
||||||
|
|
||||||
|
// Input is the name of the input file or <input> if not
|
||||||
|
// available.
|
||||||
|
Input string
|
||||||
|
|
||||||
|
// Offset is the index of the right-most failing
|
||||||
|
// token in the input text.
|
||||||
|
Offset int
|
||||||
|
|
||||||
|
// Line tells the line index of the right-most failing
|
||||||
|
// token in the input text.
|
||||||
|
//
|
||||||
|
// It is zero-based, and for error reporting, it is
|
||||||
|
// recommended to increment it by one.
|
||||||
|
Line int
|
||||||
|
|
||||||
|
// Column tells the column index of the right-most failing
|
||||||
|
// token in the input text.
|
||||||
|
Column int
|
||||||
|
|
||||||
|
// Definition tells the right-most unmatched parser definition.
|
||||||
|
Definition string
|
||||||
|
}
|
||||||
|
|
||||||
|
type parser interface {
|
||||||
|
nodeName() string
|
||||||
|
nodeID() int
|
||||||
|
commitType() CommitType
|
||||||
|
parse(*context)
|
||||||
|
}
|
||||||
|
|
||||||
|
type builder interface {
|
||||||
|
nodeName() string
|
||||||
|
nodeID() int
|
||||||
|
build(*context) ([]*Node, bool)
|
||||||
|
}
|
||||||
|
|
||||||
|
var ErrInvalidUnicodeCharacter = errors.New("invalid unicode character")
|
||||||
|
|
||||||
|
func (pe *ParseError) Error() string {
|
||||||
|
return fmt.Sprintf(
|
||||||
|
"%s:%d:%d:parse failed, parsing: %s",
|
||||||
|
pe.Input,
|
||||||
|
pe.Line+1,
|
||||||
|
pe.Column+1,
|
||||||
|
pe.Definition,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func parse(r io.Reader, p parser, b builder) (*Node, error) {
|
||||||
|
c := newContext(bufio.NewReader(r))
|
||||||
|
p.parse(c)
|
||||||
|
if c.readErr != nil {
|
||||||
|
return nil, c.readErr
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := c.finalizeParse(p); err != nil {
|
||||||
|
if perr, ok := err.(*ParseError); ok {
|
||||||
|
perr.Input = "<input>"
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
c.offset = 0
|
||||||
|
c.results.resetPending()
|
||||||
|
|
||||||
|
n, _ := b.build(c)
|
||||||
|
return n[0], nil
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user