Compare commits
No commits in common. "a8bec182b1edfbe3d1dede5509b862817da0769f" and "dbe4a5302bc4aa0846cb0f1545ae4652fe20e172" have entirely different histories.
a8bec182b1
...
dbe4a5302b
8
Makefile
8
Makefile
@ -35,15 +35,15 @@ head: $(SOURCES) fmt
|
||||
|
||||
generate: $(SOURCES) $(PARSERS) fmt head install
|
||||
treerack generate -export -package-name self < syntax.treerack > self/self.go.next
|
||||
@mv self/self.go.next self/self.go
|
||||
@mv self/self.go{.next,}
|
||||
@gofmt -s -w self/self.go
|
||||
|
||||
regenerate: $(SOURCES) $(PARSERS) fmt head install
|
||||
treerack generate -export -package-name self < syntax.treerack > self/self.go.next
|
||||
@mv self/self.go.next self/self.go
|
||||
@mv self/self.go{.next,}
|
||||
go install ./cmd/treerack
|
||||
treerack generate -export -package-name self < syntax.treerack > self/self.go.next
|
||||
@mv self/self.go.next self/self.go
|
||||
@mv self/self.go{.next,}
|
||||
@gofmt -s -w self/self.go
|
||||
|
||||
check-generate: $(SOURCES) $(PARSERS)
|
||||
@ -68,7 +68,7 @@ check-generate: $(SOURCES) $(PARSERS)
|
||||
@echo checking self
|
||||
@mv self/self.go self/self.go.backup
|
||||
@treerack generate -export -package-name self < syntax.treerack > self/self.go.next
|
||||
@mv self/self.go.next self/self.go
|
||||
@mv self/self.go{.next,}
|
||||
@gofmt -s -w self/self.go
|
||||
@if ! diff self/self.go self/self.go.backup > /dev/null; then \
|
||||
mv self/self.go.backup self/self.go; \
|
||||
|
@ -8,6 +8,6 @@
|
||||
|
||||
### Examples
|
||||
|
||||
- JSON: https://code.squareroundforest.org/arpio/treerack/blob/master/examples/json.treerack
|
||||
- Scheme: https://code.squareroundforest.org/arpio/treerack/blob/master/examples/scheme.treerack
|
||||
- Treerack (itself): https://code.squareroundforest.org/arpio/treerack/blob/master/syntax.treerack
|
||||
- JSON: https://github.com/aryszka/treerack/blob/master/examples/json.treerack
|
||||
- Scheme: https://github.com/aryszka/treerack/blob/master/examples/scheme.treerack
|
||||
- Treerack (itself): https://github.com/aryszka/treerack/blob/master/syntax.treerack
|
||||
|
13
choice.go
13
choice.go
@ -78,19 +78,6 @@ func (p *choiceParser) parse(c *context) {
|
||||
}
|
||||
|
||||
if match {
|
||||
if p.commit&NoKeyword != 0 && c.isKeyword(from, to) {
|
||||
if c.failingParser == nil &&
|
||||
p.commit&userDefined != 0 &&
|
||||
p.commit&Whitespace == 0 &&
|
||||
p.commit&FailPass == 0 {
|
||||
c.failingParser = p
|
||||
}
|
||||
|
||||
c.fail(from)
|
||||
c.results.unmarkPending(from, p.id)
|
||||
return
|
||||
}
|
||||
|
||||
if failOffset > to {
|
||||
c.failOffset = failOffset
|
||||
c.failingParser = failingParser
|
||||
|
@ -227,15 +227,6 @@ func (b *choiceBuilder) generate(w io.Writer, done map[string]bool) error {
|
||||
fprintf("name: \"%s\",", b.name)
|
||||
}
|
||||
|
||||
if len(b.generalizations) > 0 {
|
||||
fprintf("generalizations: []int{")
|
||||
for i := range b.generalizations {
|
||||
fprintf("%d,", b.generalizations[i])
|
||||
}
|
||||
|
||||
fprintf("},")
|
||||
}
|
||||
|
||||
fprintf("};")
|
||||
|
||||
if len(b.options) > 0 {
|
||||
|
@ -5,7 +5,7 @@ import (
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
const summary = `treerack - parser generator - https://code.squareroundforest.org/aryszka/treerack`
|
||||
const summary = `treerack - parser generator - https://github.com/aryszka/treerack`
|
||||
|
||||
const commandsHelp = `Available commands:
|
||||
check validates an arbitrary input against a syntax definition
|
||||
@ -18,7 +18,7 @@ See more details about a particular command by calling:
|
||||
treerack <command> -help`
|
||||
|
||||
const docRef = `See more documentation about the definition syntax and the parser output at
|
||||
https://code.squareroundforest.org/arpio/treerack.`
|
||||
https://github.com/aryszka/treerack.`
|
||||
|
||||
const positionalSyntaxUsage = "The path to the syntax file is accepted as a positional argument."
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
package main
|
||||
|
||||
import "code.squareroundforest.org/arpio/treerack"
|
||||
import "github.com/aryszka/treerack"
|
||||
|
||||
type generateOptions struct {
|
||||
command *commandOptions
|
||||
|
@ -6,7 +6,8 @@ import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"code.squareroundforest.org/arpio/treerack"
|
||||
|
||||
"github.com/aryszka/treerack"
|
||||
"golang.org/x/crypto/ssh/terminal"
|
||||
)
|
||||
|
||||
|
@ -2,7 +2,8 @@ package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"code.squareroundforest.org/arpio/treerack"
|
||||
|
||||
"github.com/aryszka/treerack"
|
||||
)
|
||||
|
||||
type showOptions struct {
|
||||
|
31
context.go
31
context.go
@ -8,11 +8,9 @@ import (
|
||||
|
||||
type context struct {
|
||||
reader io.RuneReader
|
||||
keywords []parser
|
||||
offset int
|
||||
readOffset int
|
||||
consumed int
|
||||
offsetLimit int
|
||||
failOffset int
|
||||
failingParser parser
|
||||
readErr error
|
||||
@ -22,13 +20,11 @@ type context struct {
|
||||
matchLast bool
|
||||
}
|
||||
|
||||
func newContext(r io.RuneReader, keywords []parser) *context {
|
||||
func newContext(r io.RuneReader) *context {
|
||||
return &context{
|
||||
reader: r,
|
||||
keywords: keywords,
|
||||
results: &results{},
|
||||
offsetLimit: -1,
|
||||
failOffset: -1,
|
||||
reader: r,
|
||||
results: &results{},
|
||||
failOffset: -1,
|
||||
}
|
||||
}
|
||||
|
||||
@ -62,10 +58,6 @@ func (c *context) read() bool {
|
||||
}
|
||||
|
||||
func (c *context) token() (rune, bool) {
|
||||
if c.offset == c.offsetLimit {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
if c.offset == c.readOffset {
|
||||
if !c.read() {
|
||||
return 0, false
|
||||
@ -90,21 +82,6 @@ func (c *context) fromResults(p parser) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *context) isKeyword(from, to int) bool {
|
||||
ol := c.offsetLimit
|
||||
c.offsetLimit = to
|
||||
defer func() { c.offsetLimit = ol }()
|
||||
for _, kw := range c.keywords {
|
||||
c.offset = from
|
||||
kw.parse(c)
|
||||
if c.matchLast && c.offset == to {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (c *context) success(to int) {
|
||||
c.offset = to
|
||||
c.matchLast = true
|
||||
|
@ -20,10 +20,6 @@ func flagsToCommitType(n []*Node) CommitType {
|
||||
ct |= Whitespace
|
||||
case "nows":
|
||||
ct |= NoWhitespace
|
||||
case "kw":
|
||||
ct |= Keyword
|
||||
case "nokw":
|
||||
ct |= NoKeyword
|
||||
case "failpass":
|
||||
ct |= FailPass
|
||||
case "root":
|
||||
|
750
eskip_test.go
Normal file
750
eskip_test.go
Normal file
@ -0,0 +1,750 @@
|
||||
package treerack
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/zalando/skipper/eskip"
|
||||
)
|
||||
|
||||
const (
|
||||
maxID = 27
|
||||
meanID = 9
|
||||
|
||||
setPathChance = 0.72
|
||||
maxPathTags = 12
|
||||
meanPathTags = 2
|
||||
maxPathTag = 24
|
||||
meanPathTag = 9
|
||||
|
||||
setHostChance = 0.5
|
||||
maxHost = 48
|
||||
meanHost = 24
|
||||
|
||||
setPathRegexpChance = 0.45
|
||||
maxPathRegexp = 36
|
||||
meanPathRegexp = 12
|
||||
|
||||
setMethodChance = 0.1
|
||||
|
||||
setHeadersChance = 0.3
|
||||
maxHeadersLength = 6
|
||||
meanHeadersLength = 1
|
||||
maxHeaderKeyLength = 18
|
||||
meanHeaderKeyLength = 12
|
||||
maxHeaderValueLength = 48
|
||||
meanHeaderValueLength = 6
|
||||
|
||||
setHeaderRegexpChance = 0.05
|
||||
maxHeaderRegexpsLength = 3
|
||||
meanHeaderRegexpsLength = 1
|
||||
maxHeaderRegexpLength = 12
|
||||
meanHeaderRegexpLength = 6
|
||||
|
||||
maxTermNameLength = 15
|
||||
meanTermNameLength = 6
|
||||
maxTermArgsLength = 6
|
||||
meanTermArgsLength = 1
|
||||
floatArgChance = 0.1
|
||||
intArgChance = 0.3
|
||||
maxTermStringLength = 24
|
||||
meanTermStringLength = 6
|
||||
|
||||
maxPredicatesLength = 4
|
||||
meanPredicatesLength = 1
|
||||
|
||||
maxFiltersLength = 18
|
||||
meanFiltersLength = 3
|
||||
|
||||
loopBackendChance = 0.05
|
||||
shuntBackendChance = 0.1
|
||||
maxBackend = 48
|
||||
meanBackend = 15
|
||||
)
|
||||
|
||||
func takeChance(c float64) bool {
|
||||
return rand.Float64() < c
|
||||
}
|
||||
|
||||
func generateID() string {
|
||||
return generateString(maxID, meanID)
|
||||
}
|
||||
|
||||
func generatePath() string {
|
||||
if !takeChance(setPathChance) {
|
||||
return ""
|
||||
}
|
||||
|
||||
l := randomLength(maxPathTags, meanPathTags)
|
||||
p := append(make([]string, 0, l+1), "")
|
||||
for i := 0; i < l; i++ {
|
||||
p = append(p, generateString(maxPathTag, meanPathTag))
|
||||
}
|
||||
|
||||
return strings.Join(p, "/")
|
||||
}
|
||||
|
||||
func generateHostRegexps() []string {
|
||||
if !takeChance(setHostChance) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return []string{generateString(maxHost, meanHost)}
|
||||
}
|
||||
|
||||
func generatePathRegexps() []string {
|
||||
if !takeChance(setPathRegexpChance) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return []string{generateString(maxPathRegexp, meanPathRegexp)}
|
||||
}
|
||||
|
||||
func generateMethod() string {
|
||||
if !takeChance(setMethodChance) {
|
||||
return ""
|
||||
}
|
||||
|
||||
methods := []string{"GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"}
|
||||
return methods[rand.Intn(len(methods))]
|
||||
}
|
||||
|
||||
func generateHeaders() map[string]string {
|
||||
if !takeChance(setHeadersChance) {
|
||||
return nil
|
||||
}
|
||||
|
||||
h := make(map[string]string)
|
||||
for i := 0; i < randomLength(maxHeadersLength, meanHeadersLength); i++ {
|
||||
h[generateString(maxHeaderKeyLength, meanHeaderKeyLength)] =
|
||||
generateString(maxHeaderValueLength, meanHeaderValueLength)
|
||||
}
|
||||
|
||||
return h
|
||||
}
|
||||
|
||||
func generateHeaderRegexps() map[string][]string {
|
||||
if !takeChance(setHeaderRegexpChance) {
|
||||
return nil
|
||||
}
|
||||
|
||||
h := make(map[string][]string)
|
||||
for i := 0; i < randomLength(maxHeaderRegexpsLength, meanHeaderRegexpsLength); i++ {
|
||||
k := generateString(maxHeaderKeyLength, meanHeaderKeyLength)
|
||||
for i := 0; i < randomLength(maxHeaderRegexpLength, meanHeaderRegexpLength); i++ {
|
||||
h[k] = append(h[k], generateString(maxHeaderValueLength, meanHeaderValueLength))
|
||||
}
|
||||
}
|
||||
|
||||
return h
|
||||
}
|
||||
|
||||
func generateTerm() (string, []interface{}) {
|
||||
n := generateString(maxTermNameLength, meanTermNameLength)
|
||||
al := randomLength(maxTermArgsLength, meanTermArgsLength)
|
||||
a := make([]interface{}, 0, al)
|
||||
for i := 0; i < al; i++ {
|
||||
at := rand.Float64()
|
||||
switch {
|
||||
case at < floatArgChance:
|
||||
a = append(a, rand.NormFloat64())
|
||||
case at < intArgChance:
|
||||
a = append(a, rand.Int())
|
||||
default:
|
||||
a = append(a, generateString(maxTermStringLength, meanTermStringLength))
|
||||
}
|
||||
}
|
||||
|
||||
return n, a
|
||||
}
|
||||
|
||||
func generatePredicates() []*eskip.Predicate {
|
||||
l := randomLength(maxPredicatesLength, meanPredicatesLength)
|
||||
p := make([]*eskip.Predicate, 0, l)
|
||||
for i := 0; i < l; i++ {
|
||||
pi := &eskip.Predicate{}
|
||||
pi.Name, pi.Args = generateTerm()
|
||||
p = append(p, pi)
|
||||
}
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
func generateFilters() []*eskip.Filter {
|
||||
l := randomLength(maxFiltersLength, meanFiltersLength)
|
||||
f := make([]*eskip.Filter, 0, l)
|
||||
for i := 0; i < l; i++ {
|
||||
fi := &eskip.Filter{}
|
||||
fi.Name, fi.Args = generateTerm()
|
||||
f = append(f, fi)
|
||||
}
|
||||
|
||||
return f
|
||||
}
|
||||
|
||||
func generateBackend() (eskip.BackendType, string) {
|
||||
t := rand.Float64()
|
||||
switch {
|
||||
case t < loopBackendChance:
|
||||
return eskip.LoopBackend, ""
|
||||
case t < loopBackendChance+shuntBackendChance:
|
||||
return eskip.ShuntBackend, ""
|
||||
default:
|
||||
return eskip.NetworkBackend, generateString(maxBackend, meanBackend)
|
||||
}
|
||||
}
|
||||
|
||||
func generateRoute() *eskip.Route {
|
||||
r := &eskip.Route{}
|
||||
r.Id = generateID()
|
||||
r.Path = generatePath()
|
||||
r.HostRegexps = generateHostRegexps()
|
||||
r.PathRegexps = generatePathRegexps()
|
||||
r.Method = generateMethod()
|
||||
r.Headers = generateHeaders()
|
||||
r.HeaderRegexps = generateHeaderRegexps()
|
||||
r.Predicates = generatePredicates()
|
||||
r.Filters = generateFilters()
|
||||
r.BackendType, r.Backend = generateBackend()
|
||||
return r
|
||||
}
|
||||
|
||||
func generateEskip(l int) []*eskip.Route {
|
||||
r := make([]*eskip.Route, 0, l)
|
||||
for i := 0; i < l; i++ {
|
||||
r = append(r, generateRoute())
|
||||
}
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
func parseEskipInt(s string) (int, error) {
|
||||
i, err := strconv.ParseInt(s, 0, 64)
|
||||
return int(i), err
|
||||
}
|
||||
|
||||
func parseEskipFloat(s string) (float64, error) {
|
||||
f, err := strconv.ParseFloat(s, 64)
|
||||
return f, err
|
||||
}
|
||||
|
||||
func unquote(s string, escapedChars string) (string, error) {
|
||||
if len(s) < 2 {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
b := make([]byte, 0, len(s)-2)
|
||||
var escaped bool
|
||||
for _, bi := range []byte(s[1 : len(s)-1]) {
|
||||
if escaped {
|
||||
switch bi {
|
||||
case 'b':
|
||||
bi = '\b'
|
||||
case 'f':
|
||||
bi = '\f'
|
||||
case 'n':
|
||||
bi = '\n'
|
||||
case 'r':
|
||||
bi = '\r'
|
||||
case 't':
|
||||
bi = '\t'
|
||||
case 'v':
|
||||
bi = '\v'
|
||||
}
|
||||
|
||||
b = append(b, bi)
|
||||
escaped = false
|
||||
continue
|
||||
}
|
||||
|
||||
for _, ec := range []byte(escapedChars) {
|
||||
if ec == bi {
|
||||
return "", errors.New("invalid quote")
|
||||
}
|
||||
}
|
||||
|
||||
if bi == '\\' {
|
||||
escaped = true
|
||||
continue
|
||||
}
|
||||
|
||||
b = append(b, bi)
|
||||
}
|
||||
|
||||
return string(b), nil
|
||||
}
|
||||
|
||||
func unquoteString(s string) (string, error) {
|
||||
return unquote(s, "\"")
|
||||
}
|
||||
|
||||
func unquoteRegexp(s string) (string, error) {
|
||||
return unquote(s, "/")
|
||||
}
|
||||
|
||||
func nodeToArg(n *Node) (interface{}, error) {
|
||||
switch n.Name {
|
||||
case "int":
|
||||
return parseEskipInt(n.Text())
|
||||
case "float":
|
||||
return parseEskipFloat(n.Text())
|
||||
case "string":
|
||||
return unquoteString(n.Text())
|
||||
case "regexp":
|
||||
return unquoteRegexp(n.Text())
|
||||
default:
|
||||
return nil, errors.New("invalid arg")
|
||||
}
|
||||
}
|
||||
|
||||
func nodeToTerm(n *Node) (string, []interface{}, error) {
|
||||
if len(n.Nodes) < 1 || n.Nodes[0].Name != "symbol" {
|
||||
return "", nil, errors.New("invalid term")
|
||||
}
|
||||
|
||||
name := n.Nodes[0].Text()
|
||||
|
||||
var args []interface{}
|
||||
for _, ni := range n.Nodes[1:] {
|
||||
a, err := nodeToArg(ni)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
args = append(args, a)
|
||||
}
|
||||
|
||||
return name, args, nil
|
||||
}
|
||||
|
||||
func nodeToPredicate(r *eskip.Route, n *Node) error {
|
||||
name, args, err := nodeToTerm(n)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch name {
|
||||
case "Path":
|
||||
if len(args) != 1 {
|
||||
return errors.New("invalid path predicate")
|
||||
}
|
||||
|
||||
p, ok := args[0].(string)
|
||||
if !ok {
|
||||
return errors.New("invalid path predicate")
|
||||
}
|
||||
|
||||
r.Path = p
|
||||
case "Host":
|
||||
if len(args) != 1 {
|
||||
return errors.New("invalid host predicate")
|
||||
}
|
||||
|
||||
h, ok := args[0].(string)
|
||||
if !ok {
|
||||
return errors.New("invalid host predicate")
|
||||
}
|
||||
|
||||
r.HostRegexps = append(r.HostRegexps, h)
|
||||
case "PathRegexp":
|
||||
if len(args) != 1 {
|
||||
return errors.New("invalid path regexp predicate")
|
||||
}
|
||||
|
||||
p, ok := args[0].(string)
|
||||
if !ok {
|
||||
return errors.New("invalid path regexp predicate")
|
||||
}
|
||||
|
||||
r.PathRegexps = append(r.PathRegexps, p)
|
||||
case "Method":
|
||||
if len(args) != 1 {
|
||||
return errors.New("invalid method predicate")
|
||||
}
|
||||
|
||||
m, ok := args[0].(string)
|
||||
if !ok {
|
||||
return errors.New("invalid method predicate")
|
||||
}
|
||||
|
||||
r.Method = m
|
||||
case "Header":
|
||||
if len(args) != 2 {
|
||||
return errors.New("invalid header predicate")
|
||||
}
|
||||
|
||||
name, ok := args[0].(string)
|
||||
if !ok {
|
||||
return errors.New("invalid header predicate")
|
||||
}
|
||||
|
||||
value, ok := args[1].(string)
|
||||
if !ok {
|
||||
return errors.New("invalid header predicate")
|
||||
}
|
||||
|
||||
if r.Headers == nil {
|
||||
r.Headers = make(map[string]string)
|
||||
}
|
||||
|
||||
r.Headers[name] = value
|
||||
case "HeaderRegexp":
|
||||
if len(args) != 2 {
|
||||
return errors.New("invalid header regexp predicate")
|
||||
}
|
||||
|
||||
name, ok := args[0].(string)
|
||||
if !ok {
|
||||
return errors.New("invalid header regexp predicate")
|
||||
}
|
||||
|
||||
value, ok := args[1].(string)
|
||||
if !ok {
|
||||
return errors.New("invalid header regexp predicate")
|
||||
}
|
||||
|
||||
if r.HeaderRegexps == nil {
|
||||
r.HeaderRegexps = make(map[string][]string)
|
||||
}
|
||||
|
||||
r.HeaderRegexps[name] = append(r.HeaderRegexps[name], value)
|
||||
default:
|
||||
r.Predicates = append(r.Predicates, &eskip.Predicate{Name: name, Args: args})
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func nodeToFilter(n *Node) (*eskip.Filter, error) {
|
||||
name, args, err := nodeToTerm(n)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &eskip.Filter{Name: name, Args: args}, nil
|
||||
}
|
||||
|
||||
func nodeToBackend(r *eskip.Route, n *Node) error {
|
||||
switch n.Name {
|
||||
case "string":
|
||||
b, err := unquoteString(n.Text())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
r.BackendType = eskip.NetworkBackend
|
||||
r.Backend = b
|
||||
case "shunt":
|
||||
r.BackendType = eskip.ShuntBackend
|
||||
case "loopback":
|
||||
r.BackendType = eskip.LoopBackend
|
||||
default:
|
||||
return errors.New("invalid backend type")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func nodeToEskipDefinition(n *Node) (*eskip.Route, error) {
|
||||
ns := n.Nodes
|
||||
if len(ns) < 2 || len(ns[1].Nodes) == 0 {
|
||||
return nil, fmt.Errorf("invalid definition length: %d", len(ns))
|
||||
}
|
||||
|
||||
r := &eskip.Route{}
|
||||
|
||||
if ns[0].Name != "symbol" {
|
||||
return nil, errors.New("invalid definition id")
|
||||
}
|
||||
|
||||
r.Id, ns = ns[0].Text(), ns[1].Nodes
|
||||
|
||||
predicates:
|
||||
for i, ni := range ns {
|
||||
switch ni.Name {
|
||||
case "predicate":
|
||||
if err := nodeToPredicate(r, ni); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case "filter", "string", "shunt", "loopback":
|
||||
ns = ns[i:]
|
||||
break predicates
|
||||
default:
|
||||
return nil, errors.New("invalid definition item among predicates")
|
||||
}
|
||||
}
|
||||
|
||||
filters:
|
||||
for i, ni := range ns {
|
||||
switch ni.Name {
|
||||
case "filter":
|
||||
f, err := nodeToFilter(ni)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
r.Filters = append(r.Filters, f)
|
||||
case "string", "shunt", "loopback":
|
||||
ns = ns[i:]
|
||||
break filters
|
||||
default:
|
||||
return nil, errors.New("invalid definition item among filters")
|
||||
}
|
||||
}
|
||||
|
||||
if len(ns) != 1 {
|
||||
return nil, fmt.Errorf("invalid definition backend, remaining definition length: %d, %s",
|
||||
len(ns), n.Text())
|
||||
}
|
||||
|
||||
if err := nodeToBackend(r, ns[0]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func eskipTreeToEskip(n []*Node) ([]*eskip.Route, error) {
|
||||
r := make([]*eskip.Route, 0, len(n))
|
||||
for _, ni := range n {
|
||||
d, err := nodeToEskipDefinition(ni)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
r = append(r, d)
|
||||
}
|
||||
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func checkTerm(t *testing.T, gotName, expectedName string, gotArgs, expectedArgs []interface{}) {
|
||||
if gotName != expectedName {
|
||||
t.Error("invalid term name")
|
||||
return
|
||||
}
|
||||
|
||||
if len(gotArgs) != len(expectedArgs) {
|
||||
t.Error("invalid term args length in:", gotName, len(gotArgs), len(expectedArgs))
|
||||
return
|
||||
}
|
||||
|
||||
// legacy bug support, dropping numeric arguments:
|
||||
for i, a := range gotArgs {
|
||||
ea := expectedArgs[i]
|
||||
switch a.(type) {
|
||||
case int, float64:
|
||||
switch ea.(type) {
|
||||
case int, float64:
|
||||
gotArgs = append(gotArgs[:i], gotArgs[i+1:]...)
|
||||
expectedArgs = append(expectedArgs[:i], expectedArgs[i+1:]...)
|
||||
default:
|
||||
t.Error("invalid argument type at:", i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for i, a := range gotArgs {
|
||||
if a != expectedArgs[i] {
|
||||
t.Error("invalid term arg")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func checkPredicates(t *testing.T, got, expected *eskip.Route) {
|
||||
if got.Path != expected.Path {
|
||||
t.Error("invalid path")
|
||||
return
|
||||
}
|
||||
|
||||
if len(got.HostRegexps) != len(expected.HostRegexps) {
|
||||
t.Error("invalid host length")
|
||||
return
|
||||
}
|
||||
|
||||
for i, h := range got.HostRegexps {
|
||||
if h != expected.HostRegexps[i] {
|
||||
t.Error("invalid host")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if len(got.PathRegexps) != len(expected.PathRegexps) {
|
||||
t.Error("invalid path regexp length", len(got.PathRegexps), len(expected.PathRegexps))
|
||||
return
|
||||
}
|
||||
|
||||
for i, h := range got.PathRegexps {
|
||||
if h != expected.PathRegexps[i] {
|
||||
t.Error("invalid path regexp")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if got.Method != expected.Method {
|
||||
t.Error("invalid method")
|
||||
return
|
||||
}
|
||||
|
||||
if len(got.Headers) != len(expected.Headers) {
|
||||
t.Error("invalid headers length")
|
||||
return
|
||||
}
|
||||
|
||||
for n, h := range got.Headers {
|
||||
he, ok := expected.Headers[n]
|
||||
if !ok {
|
||||
t.Error("invalid header name")
|
||||
return
|
||||
}
|
||||
|
||||
if he != h {
|
||||
t.Error("invalid header")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if len(got.HeaderRegexps) != len(expected.HeaderRegexps) {
|
||||
t.Error("invalid header regexp length")
|
||||
return
|
||||
}
|
||||
|
||||
for n, h := range got.HeaderRegexps {
|
||||
he, ok := expected.HeaderRegexps[n]
|
||||
if !ok {
|
||||
t.Error("invalid header regexp name")
|
||||
return
|
||||
}
|
||||
|
||||
if len(h) != len(he) {
|
||||
t.Error("invalid header regexp item length")
|
||||
return
|
||||
}
|
||||
|
||||
for i, hi := range h {
|
||||
if hi != he[i] {
|
||||
t.Error("invalid header regexp")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(got.Predicates) != len(expected.Predicates) {
|
||||
t.Error("invalid predicates length")
|
||||
return
|
||||
}
|
||||
|
||||
for i, p := range got.Predicates {
|
||||
checkTerm(
|
||||
t,
|
||||
p.Name, expected.Predicates[i].Name,
|
||||
p.Args, expected.Predicates[i].Args,
|
||||
)
|
||||
|
||||
if t.Failed() {
|
||||
t.Log(p.Name, expected.Predicates[i].Name)
|
||||
t.Log(p.Args, expected.Predicates[i].Args)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func checkFilters(t *testing.T, got, expected []*eskip.Filter) {
|
||||
if len(got) != len(expected) {
|
||||
t.Error("invalid filters length")
|
||||
return
|
||||
}
|
||||
|
||||
for i, f := range got {
|
||||
checkTerm(
|
||||
t,
|
||||
f.Name, expected[i].Name,
|
||||
f.Args, expected[i].Args,
|
||||
)
|
||||
|
||||
if t.Failed() {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func checkBackend(t *testing.T, got, expected *eskip.Route) {
|
||||
if got.BackendType != expected.BackendType {
|
||||
t.Error("invalid backend type")
|
||||
return
|
||||
}
|
||||
|
||||
if got.Backend != expected.Backend {
|
||||
t.Error("invalid backend")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func checkRoute(t *testing.T, got, expected *eskip.Route) {
|
||||
if got.Id != expected.Id {
|
||||
t.Error("invalid route id")
|
||||
return
|
||||
}
|
||||
|
||||
checkPredicates(t, got, expected)
|
||||
if t.Failed() {
|
||||
return
|
||||
}
|
||||
|
||||
checkFilters(t, got.Filters, expected.Filters)
|
||||
if t.Failed() {
|
||||
return
|
||||
}
|
||||
|
||||
checkBackend(t, got, expected)
|
||||
}
|
||||
|
||||
func checkEskip(t *testing.T, got, expected []*eskip.Route) {
|
||||
if len(got) != len(expected) {
|
||||
t.Error("invalid length", len(got), len(expected))
|
||||
return
|
||||
}
|
||||
|
||||
for i, ri := range got {
|
||||
checkRoute(t, ri, expected[i])
|
||||
if t.Failed() {
|
||||
t.Log(ri.String())
|
||||
t.Log(expected[i].String())
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestEskip(t *testing.T) {
|
||||
const count = 1 << 9
|
||||
|
||||
r := generateEskip(count)
|
||||
e := eskip.Print(eskip.PrettyPrintInfo{Pretty: true}, r...)
|
||||
b := bytes.NewBufferString(e)
|
||||
|
||||
s, err := openSyntaxFile("examples/eskip.treerack")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
n, err := s.Parse(b)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
rback, err := eskipTreeToEskip(n.Nodes)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
checkEskip(t, rback, r)
|
||||
}
|
50
examples/eskip.treerack
Normal file
50
examples/eskip.treerack
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
Eskip routing configuration format for Skipper: https://github.com/zalando/skipper
|
||||
*/
|
||||
|
||||
eskip:root = (expression | definitions)?;
|
||||
|
||||
space:ws = [ \n\b\f\r\t\v];
|
||||
comment:ws = "//" [^\n]*;
|
||||
|
||||
decimal-digit:alias = [0-9];
|
||||
octal-digit:alias = [0-7];
|
||||
hexa-digit:alias = [0-9a-fA-F];
|
||||
|
||||
decimal:alias:nows = [1-9] decimal-digit*;
|
||||
octal:alias:nows = "0" octal-digit*;
|
||||
hexa:alias:nows = "0" [xX] hexa-digit+;
|
||||
int = decimal | octal | hexa;
|
||||
|
||||
exponent:alias:nows = [eE] [+\-]? decimal-digit+;
|
||||
float:nows = decimal-digit+ "." decimal-digit* exponent?
|
||||
| "." decimal-digit+ exponent?
|
||||
| decimal-digit+ exponent;
|
||||
|
||||
number:alias:nows = "-"? (int | float);
|
||||
|
||||
string:nows = "\"" ([^\\"] | "\\" .)* "\"";
|
||||
regexp:nows = "/" ([^\\/] | "\\" .)* "/";
|
||||
symbol:nows = [a-zA-Z_] [a-zA-z0-9_]*;
|
||||
|
||||
arg:alias = number | string | regexp;
|
||||
args:alias = arg ("," arg)*;
|
||||
term:alias = symbol "(" args? ")";
|
||||
|
||||
predicate = term;
|
||||
predicates:alias = "*" | predicate ("&&" predicate)*;
|
||||
|
||||
filter = term;
|
||||
filters:alias = filter ("->" filter)*;
|
||||
|
||||
address:alias = string;
|
||||
shunt = "<shunt>";
|
||||
loopback = "<loopback>";
|
||||
backend:alias = address | shunt | loopback;
|
||||
|
||||
expression = predicates ("->" filters)? "->" backend;
|
||||
|
||||
id:alias = symbol;
|
||||
definition = id ":" expression;
|
||||
|
||||
definitions:alias = ";"* definition (";"+ definition)* ";"*;
|
@ -1,271 +0,0 @@
|
||||
ws:ws = " " | "\b" | "\f" | "\r" | "\t" | "\v";
|
||||
wsc:ws = comment;
|
||||
nl:alias = "\n";
|
||||
|
||||
line-comment-content:nows = [^\n]*;
|
||||
line-comment:alias:nows = "//" line-comment-content;
|
||||
block-comment-content:nows = ([^*] | "*" [^/])*;
|
||||
block-comment:alias:nows = "/*" block-comment-content "*/";
|
||||
comment-part:alias = line-comment | block-comment;
|
||||
comment:alias = comment-part (nl? comment-part)*;
|
||||
|
||||
decimal-digit:alias = [0-9];
|
||||
octal-digit:alias = [0-7];
|
||||
hexa-digit:alias = [0-9a-fA-F];
|
||||
|
||||
decimal:alias:nows = [1-9] decimal-digit*;
|
||||
octal:alias:nows = "0" octal-digit*;
|
||||
hexa:alias:nows = "0" [xX] hexa-digit+;
|
||||
int = decimal | octal | hexa;
|
||||
|
||||
exponent:alias:nows = [eE] [+\-]? decimal-digit+;
|
||||
float:nows = decimal-digit+ "." decimal-digit* exponent?
|
||||
| "." decimal-digit+ exponent?
|
||||
| decimal-digit+ exponent;
|
||||
|
||||
string:nows = "\"" ([^\\"] | "\\" .)* "\"";
|
||||
|
||||
true = "true";
|
||||
false = "false";
|
||||
bool:alias = true | false;
|
||||
|
||||
symbol:nows = [a-zA-Z_][a-zA-Z_0-9]*;
|
||||
|
||||
spread-expression = primary-expression "...";
|
||||
list-sep:alias = (nl | ",")+;
|
||||
list-item:alias = expression | spread-expression;
|
||||
expression-list:alias = list-item (list-sep list-item)*;
|
||||
|
||||
list-fact:alias = "[" list-sep? expression-list? list-sep? "]";
|
||||
list = list-fact;
|
||||
mutable-list = "~" nl* list-fact;
|
||||
|
||||
expression-key = "[" nl* expression nl* "]";
|
||||
entry = (symbol | string | expression-key) nl* ":" nl* expression;
|
||||
entry-list:alias = (entry | spread-expression) (list-sep (entry | spread-expression))*;
|
||||
struct-fact:alias = "{" list-sep? entry-list? list-sep? "}";
|
||||
struct = struct-fact;
|
||||
mutable-struct = "~" nl* struct-fact;
|
||||
|
||||
parameter-list:alias = symbol (list-sep symbol)*;
|
||||
collect-parameter = "..." nl* symbol;
|
||||
return = "return" (nl* expression)?;
|
||||
block = "{" sep? statement-list? sep? "}";
|
||||
function-fact:alias = "(" list-sep?
|
||||
(parameter-list
|
||||
| parameter-list list-sep collect-parameter
|
||||
| collect-parameter)?
|
||||
list-sep? ")" nl*
|
||||
(simple-statement | block);
|
||||
function = "fn" nl* function-fact;
|
||||
effect = "fn" nl* "~" nl* function-fact;
|
||||
|
||||
range-from = expression;
|
||||
range-to = expression;
|
||||
range:alias = range-from? nl* ":" nl* range-to?;
|
||||
|
||||
symbol-index = "." nl* symbol;
|
||||
expression-index = "[" nl* expression nl* "]";
|
||||
index:alias = symbol-index | expression-index;
|
||||
index-list:alias = index (nl* index)?;
|
||||
indexer = primary-expression nl* index-list;
|
||||
|
||||
function-application = primary-expression "(" list-sep? expression-list? list-sep? ")";
|
||||
|
||||
expression-group:alias = "(" nl* expression nl* ")";
|
||||
primary-expression:alias = int
|
||||
| float
|
||||
| string
|
||||
| bool
|
||||
| receive
|
||||
| symbol
|
||||
| list
|
||||
| mutable-list
|
||||
| struct
|
||||
| mutable-struct
|
||||
| function
|
||||
| effect
|
||||
| indexer
|
||||
| function-application
|
||||
| expression-group;
|
||||
|
||||
binary-not = "^";
|
||||
binary-and = "&";
|
||||
binary-or = "|";
|
||||
xor = "^";
|
||||
and-not = "&^";
|
||||
lshift = "<<";
|
||||
rshift = ">>";
|
||||
|
||||
plus = "+";
|
||||
minus = "-";
|
||||
mul = "*";
|
||||
div = "/";
|
||||
mod = "%";
|
||||
add = "+";
|
||||
sub = "-";
|
||||
|
||||
logical-not = "!";
|
||||
eq = "==";
|
||||
not-eq = "!=";
|
||||
less = "<";
|
||||
less-or-eq = "<=";
|
||||
greater = ">";
|
||||
greater-or-eq = ">=";
|
||||
logical-and = "&&";
|
||||
logical-or = "||";
|
||||
|
||||
chain:alias = "->";
|
||||
|
||||
unary-operator:alias = plus | minus | binary-not | logical-not;
|
||||
unary-expression = unary-operator primary-expression;
|
||||
|
||||
binary-op0:alias = binary-and | and-not | lshift | rshift | mul | div | mod;
|
||||
binary-op1:alias = binary-or | xor | add | sub;
|
||||
binary-op2:alias = eq | not-eq | less | less-or-eq | greater | greater-or-eq;
|
||||
binary-op3:alias = logical-and;
|
||||
binary-op4:alias = logical-or;
|
||||
|
||||
operand0:alias = primary-expression | unary-expression;
|
||||
operand1:alias = operand0 | binary0;
|
||||
operand2:alias = operand1 | binary1;
|
||||
operand3:alias = operand2 | binary2;
|
||||
operand4:alias = operand3 | binary3;
|
||||
operand5:alias = operand4 | binary4;
|
||||
|
||||
binary0 = operand0 (nl* binary-op0 nl* operand0)+;
|
||||
binary1 = operand1 (nl* binary-op1 nl* operand1)+;
|
||||
binary2 = operand2 (nl* binary-op2 nl* operand2)+;
|
||||
binary3 = operand3 (nl* binary-op3 nl* operand3)+;
|
||||
binary4 = operand4 (nl* binary-op4 nl* operand4)+;
|
||||
|
||||
binary-expression:alias = binary0
|
||||
| binary1
|
||||
| binary2
|
||||
| binary3
|
||||
| binary4;
|
||||
|
||||
ternary-expression = expression nl* "?" nl* expression nl* ":" nl* expression;
|
||||
|
||||
chainingOperand:alias = primary-expression
|
||||
| unary-expression
|
||||
| binary-expression
|
||||
| ternary-expression;
|
||||
chaining = chainingOperand (nl* chain nl* chainingOperand)+;
|
||||
|
||||
expression:alias = primary-expression
|
||||
| unary-expression
|
||||
| binary-expression
|
||||
| ternary-expression
|
||||
| chaining;
|
||||
|
||||
if = "if" nl* expression nl* block
|
||||
(nl* "else" nl* "if" nl* expression nl* block)*
|
||||
(nl* "else" nl* block)?;
|
||||
|
||||
// TODO: empty switch not parsed
|
||||
default = "default" nl* ":";
|
||||
default-line:alias = default ";"* statement?;
|
||||
case = "case" nl* expression nl* ":";
|
||||
case-line:alias = case ";"* statement?;
|
||||
switch = "switch" nl* expression? nl* "{" sep?
|
||||
((case-line | default-line) (sep (case-line | default-line | statement))*)?
|
||||
sep? "}";
|
||||
|
||||
send = "send" nl* primary-expression nl* primary-expression;
|
||||
receive = "receive" nl* primary-expression;
|
||||
receive-definition = symbol nl* receive;
|
||||
communication:alias = send | receive | receive-definition;
|
||||
select-case = "case" nl* communication nl* ":";
|
||||
select-case-line:alias = select-case ";"* statement?;
|
||||
select = "select" nl* "{" sep?
|
||||
((select-case-line | default-line)
|
||||
(sep (select-case-line | default-line | statement))*)?
|
||||
sep? "}";
|
||||
|
||||
go = "go" nl* function-application;
|
||||
defer = "defer" nl* function-application;
|
||||
|
||||
range-over-expression = symbol nl* "in" nl* (expression | range) | range;
|
||||
loop-expression:alias = expression | range-over-expression;
|
||||
loop = "for" ((nl* loop-expression)? nl* block | nl* block);
|
||||
|
||||
// TODO: set(a b)
|
||||
assign-capture:alias = primary-expression (nl* "=")? nl* expression;
|
||||
assign-capture-list:alias = assign-capture (list-sep assign-capture)*;
|
||||
assign-set:alias = "set" nl* assign-capture;
|
||||
assign-eq:alias = primary-expression nl* "=" nl* expression;
|
||||
assign-group:alias = "set" nl* "(" (list-sep assign-capture-list)? list-sep? ")";
|
||||
assignment = assign-set | assign-eq | assign-group;
|
||||
|
||||
value-capture-fact:alias = symbol (nl* "=")? nl* expression;
|
||||
value-capture = value-capture-fact;
|
||||
mutable-capture = "~" nl* value-capture-fact;
|
||||
value-definition = "let" nl* (value-capture | mutable-capture);
|
||||
mixed-capture-list:alias = (value-capture | mutable-capture) (list-sep (value-capture | mutable-capture))*;
|
||||
value-capture-list:alias = value-capture (list-sep value-capture)*;
|
||||
value-definition-group = "let" nl* "(" list-sep? mixed-capture-list? list-sep? ")";
|
||||
mutable-definition-group = "let" nl* "~" nl* "(" list-sep? value-capture-list? list-sep? ")";
|
||||
|
||||
function-definition-fact:alias = symbol nl* function-fact;
|
||||
function-capture = function-definition-fact;
|
||||
effect-capture = "~" nl* function-definition-fact;
|
||||
function-definition = "fn" nl* (function-capture | effect-capture);
|
||||
function-capture-list:alias = function-capture (list-sep function-capture)*;
|
||||
mixed-function-capture-list:alias = (function-capture | effect-capture)
|
||||
(list-sep (function-capture | effect-capture))*;
|
||||
function-definition-group = "fn" nl* "(" list-sep?
|
||||
mixed-function-capture-list?
|
||||
list-sep? ")";
|
||||
effect-definition-group = "fn" nl* "~" nl* "(" list-sep?
|
||||
function-capture-list?
|
||||
list-sep? ")";
|
||||
|
||||
definition:alias = value-definition
|
||||
| value-definition-group
|
||||
| mutable-definition-group
|
||||
| function-definition
|
||||
| function-definition-group
|
||||
| effect-definition-group;
|
||||
|
||||
// TODO:
|
||||
// - use effect
|
||||
// - rename to 'use'
|
||||
|
||||
use-inline = ".";
|
||||
use-fact = string
|
||||
| (symbol | use-inline) (nl* "=")? nl* string;
|
||||
use-fact-list:alias = use-fact (list-sep use-fact)*;
|
||||
use-statement:alias = "use" nl* use-fact;
|
||||
use-statement-group:alias = "use" nl* "(" list-sep?
|
||||
use-fact-list?
|
||||
list-sep? ")";
|
||||
use = use-statement | use-statement-group;
|
||||
|
||||
export = "export" nl* definition;
|
||||
|
||||
simple-statement:alias = send
|
||||
| go
|
||||
| defer
|
||||
| assignment
|
||||
| simple-statement-group
|
||||
| expression;
|
||||
simple-statement-group:alias = "(" nl* simple-statement nl* ")";
|
||||
statement:alias = return
|
||||
| if
|
||||
| switch
|
||||
| select
|
||||
| loop
|
||||
| definition
|
||||
| use
|
||||
| export
|
||||
| statement-group
|
||||
| simple-statement;
|
||||
statement-group:alias = "(" nl* statement nl* ")";
|
||||
|
||||
sep:alias = (";" | nl)+;
|
||||
statement-list:alias = statement (sep statement)*;
|
||||
|
||||
shebang-command = [^\n]*;
|
||||
shebang = "#!" shebang-command "\n";
|
||||
mml:root = shebang? sep? statement-list? sep?;
|
@ -1,271 +0,0 @@
|
||||
ws:ws = " " | "\b" | "\f" | "\r" | "\t" | "\v";
|
||||
wsc:ws = comment;
|
||||
nl:alias = "\n";
|
||||
wsep:alias = ws | nl;
|
||||
|
||||
line-comment-content:nows = [^\n]*;
|
||||
line-comment:alias:nows = "//" line-comment-content;
|
||||
block-comment-content:nows = ([^*] | "*" [^/])*;
|
||||
block-comment:alias:nows = "/*" block-comment-content "*/";
|
||||
comment-part:alias = line-comment | block-comment;
|
||||
comment:alias = comment-part (nl? comment-part)*;
|
||||
|
||||
decimal-digit:alias = [0-9];
|
||||
octal-digit:alias = [0-7];
|
||||
hexa-digit:alias = [0-9a-fA-F];
|
||||
|
||||
decimal:alias:nows = [1-9] decimal-digit*;
|
||||
octal:alias:nows = "0" octal-digit*;
|
||||
hexa:alias:nows = "0" [xX] hexa-digit+;
|
||||
int = decimal | octal | hexa;
|
||||
|
||||
exponent:alias:nows = [eE] [+\-]? decimal-digit+;
|
||||
float:nows = decimal-digit+ "." decimal-digit* exponent?
|
||||
| "." decimal-digit+ exponent?
|
||||
| decimal-digit+ exponent;
|
||||
|
||||
string:nows = "\"" ([^\\"] | "\\" .)* "\"";
|
||||
|
||||
true = "true";
|
||||
false = "false";
|
||||
bool:alias = true | false;
|
||||
|
||||
symbol:nows = [a-zA-Z_][a-zA-Z_0-9]*;
|
||||
|
||||
spread-expression = primary-expression "...";
|
||||
list-sep:alias = (nl | ",")+;
|
||||
list-item:alias = expression | spread-expression;
|
||||
expression-list:alias = list-item (list-sep list-item)*;
|
||||
|
||||
list-fact:alias = "[" list-sep? expression-list? list-sep? "]";
|
||||
list = list-fact;
|
||||
mutable-list = "~" nl* list-fact;
|
||||
|
||||
expression-key = "[" nl* expression nl* "]";
|
||||
entry = (symbol | string | expression-key) nl* ":" nl* expression;
|
||||
entry-list:alias = (entry | spread-expression) (list-sep (entry | spread-expression))*;
|
||||
struct-fact:alias = "{" list-sep? entry-list? list-sep? "}";
|
||||
struct = struct-fact;
|
||||
mutable-struct = "~" nl* struct-fact;
|
||||
|
||||
parameter-list:alias = symbol (list-sep symbol)*;
|
||||
collect-parameter = "..." nl* symbol;
|
||||
return = "return" | "return" nl* expression;
|
||||
block = "{" sep? statement-list? sep? "}";
|
||||
function-fact:alias = "(" list-sep?
|
||||
(parameter-list
|
||||
| parameter-list list-sep collect-parameter
|
||||
| collect-parameter)?
|
||||
list-sep? ")" nl*
|
||||
(expression | simple-statement | block);
|
||||
function = "fn" nl* function-fact;
|
||||
effect = "fn" nl* "~" nl* function-fact;
|
||||
|
||||
range-from = expression;
|
||||
range-to = expression;
|
||||
range:alias = range-from? nl* ":" nl* range-to?;
|
||||
|
||||
symbol-index = "." nl* symbol;
|
||||
expression-index = "[" nl* expression nl* "]";
|
||||
range-index = "[" nl* range nl* "]";
|
||||
index:alias = symbol-index | expression-index | range-index;
|
||||
index-list:alias = index (nl* index)?;
|
||||
indexer = primary-expression nl* index-list;
|
||||
|
||||
application = primary-expression "(" list-sep? expression-list? list-sep? ")";
|
||||
|
||||
expression-group:alias = "(" nl* expression nl* ")";
|
||||
primary-expression:alias = int
|
||||
| float
|
||||
| string
|
||||
| bool
|
||||
| symbol
|
||||
| list
|
||||
| mutable-list
|
||||
| struct
|
||||
| mutable-struct
|
||||
| function
|
||||
| effect
|
||||
| indexer
|
||||
| application
|
||||
| receive
|
||||
| expression-group;
|
||||
|
||||
binary-not = "^";
|
||||
binary-and = "&";
|
||||
binary-or = "|";
|
||||
xor = "^";
|
||||
and-not = "&^";
|
||||
lshift = "<<";
|
||||
rshift = ">>";
|
||||
|
||||
plus = "+";
|
||||
minus = "-";
|
||||
mul = "*";
|
||||
div = "/";
|
||||
mod = "%";
|
||||
add = "+";
|
||||
sub = "-";
|
||||
|
||||
logical-not = "!";
|
||||
eq = "==";
|
||||
not-eq = "!=";
|
||||
less = "<";
|
||||
less-or-eq = "<=";
|
||||
greater = ">";
|
||||
greater-or-eq = ">=";
|
||||
logical-and = "&&";
|
||||
logical-or = "||";
|
||||
|
||||
chain:alias = "->";
|
||||
|
||||
unary-operator:alias = plus | minus | binary-not | logical-not;
|
||||
unary-expression = unary-operator primary-expression;
|
||||
|
||||
binary-op0:alias = binary-and | and-not | lshift | rshift | mul | div | mod;
|
||||
binary-op1:alias = binary-or | xor | add | sub;
|
||||
binary-op2:alias = eq | not-eq | less | less-or-eq | greater | greater-or-eq;
|
||||
binary-op3:alias = logical-and;
|
||||
binary-op4:alias = logical-or;
|
||||
|
||||
operand0:alias = primary-expression | unary-expression;
|
||||
operand1:alias = operand0 | binary0;
|
||||
operand2:alias = operand1 | binary1;
|
||||
operand3:alias = operand2 | binary2;
|
||||
operand4:alias = operand3 | binary3;
|
||||
operand5:alias = operand4 | binary4;
|
||||
|
||||
binary0 = operand0 (nl* binary-op0 nl* operand0)+;
|
||||
binary1 = operand1 (nl* binary-op1 nl* operand1)+;
|
||||
binary2 = operand2 (nl* binary-op2 nl* operand2)+;
|
||||
binary3 = operand3 (nl* binary-op3 nl* operand3)+;
|
||||
binary4 = operand4 (nl* binary-op4 nl* operand4)+;
|
||||
|
||||
binary-expression:alias = binary0
|
||||
| binary1
|
||||
| binary2
|
||||
| binary3
|
||||
| binary4;
|
||||
|
||||
ternary-expression = expression nl* "?" nl* expression nl* ":" nl* expression;
|
||||
|
||||
chainingOperand:alias = primary-expression
|
||||
| unary-expression
|
||||
| binary-expression
|
||||
| ternary-expression;
|
||||
chaining = chainingOperand (nl* chain nl* chainingOperand)+;
|
||||
|
||||
expression:alias = primary-expression
|
||||
| unary-expression
|
||||
| binary-expression
|
||||
| ternary-expression
|
||||
| chaining;
|
||||
|
||||
if = "if" nl* expression nl* block
|
||||
(nl* "else" nl* "if" nl* expression nl* block)*
|
||||
(nl* "else" nl* block)?;
|
||||
|
||||
// TODO: empty switch not parsed
|
||||
default = "default" nl* ":";
|
||||
default-line:alias = default ";"* statement?;
|
||||
case = "case" nl* expression nl* ":";
|
||||
case-line:alias = case ";"* statement?;
|
||||
switch = "switch" nl* expression? nl* "{" sep?
|
||||
((case-line | default-line) (sep (case-line | default-line | statement))*)?
|
||||
sep? "}";
|
||||
|
||||
send = "send" nl* primary-expression nl* primary-expression;
|
||||
receive = "receive" nl* primary-expression;
|
||||
receive-definition = symbol nl* receive;
|
||||
communication:alias = send | receive | receive-definition;
|
||||
select-case = "case" nl* communication nl* ":";
|
||||
select-case-line:alias = select-case ";"* statement?;
|
||||
select = "select" nl* "{" sep?
|
||||
((select-case-line | default-line)
|
||||
(sep (select-case-line | default-line | statement))*)?
|
||||
sep? "}";
|
||||
|
||||
go = "go" nl* application;
|
||||
defer = "defer" nl* application;
|
||||
|
||||
break = "break";
|
||||
continue = "continue";
|
||||
loop-control:alias = break | continue;
|
||||
range-over = symbol nl* "in" nl* (expression | range) | range;
|
||||
loop-expression:alias = expression | range-over;
|
||||
loop = "for" ((nl* loop-expression)? nl* block | nl* block);
|
||||
|
||||
assignment = (symbol | indexer) nl* "=" nl* expression;
|
||||
|
||||
value-capture-fact:alias = symbol (nl* "=")? nl* expression;
|
||||
value-capture = value-capture-fact;
|
||||
mutable-capture = "~" nl* value-capture-fact;
|
||||
value-definition = "let" nl* (value-capture | mutable-capture);
|
||||
mixed-capture-list:alias = (value-capture | mutable-capture) (list-sep (value-capture | mutable-capture))*;
|
||||
value-capture-list:alias = value-capture (list-sep value-capture)*;
|
||||
value-definition-group = "let" nl* "(" list-sep? mixed-capture-list? list-sep? ")";
|
||||
mutable-definition-group = "let" nl* "~" nl* "(" list-sep? value-capture-list? list-sep? ")";
|
||||
|
||||
function-definition-fact:alias = symbol nl* function-fact;
|
||||
function-capture = function-definition-fact;
|
||||
effect-capture = "~" nl* function-definition-fact;
|
||||
function-definition = "fn" nl* (function-capture | effect-capture);
|
||||
function-capture-list:alias = function-capture (list-sep function-capture)*;
|
||||
mixed-function-capture-list:alias = (function-capture | effect-capture)
|
||||
(list-sep (function-capture | effect-capture))*;
|
||||
function-definition-group = "fn" nl* "(" list-sep?
|
||||
mixed-function-capture-list?
|
||||
list-sep? ")";
|
||||
effect-definition-group = "fn" nl* "~" nl* "(" list-sep?
|
||||
function-capture-list?
|
||||
list-sep? ")";
|
||||
|
||||
definition:alias = value-definition
|
||||
| value-definition-group
|
||||
| mutable-definition-group
|
||||
| function-definition
|
||||
| function-definition-group
|
||||
| effect-definition-group;
|
||||
|
||||
// TODO:
|
||||
// - use effect
|
||||
|
||||
use-inline = ".";
|
||||
use-fact = string
|
||||
| (symbol | use-inline) (nl* "=")? nl* string;
|
||||
use-fact-list:alias = use-fact (list-sep use-fact)*;
|
||||
use-statement:alias = "use" nl* use-fact;
|
||||
use-statement-group:alias = "use" nl* "(" list-sep?
|
||||
use-fact-list?
|
||||
list-sep? ")";
|
||||
use = use-statement | use-statement-group;
|
||||
|
||||
export = "export" nl* definition;
|
||||
|
||||
simple-statement:alias = send
|
||||
| go
|
||||
| defer
|
||||
| assignment
|
||||
| simple-statement-group;
|
||||
simple-statement-group:alias = "(" nl* simple-statement nl* ")";
|
||||
statement:alias = simple-statement
|
||||
| return
|
||||
| if
|
||||
| switch
|
||||
| select
|
||||
| loop
|
||||
| loop-control
|
||||
| definition
|
||||
| use
|
||||
| export
|
||||
| application // TODO: sendSomething() and sendSomething
|
||||
| chaining
|
||||
| statement-group;
|
||||
statement-group:alias = "(" nl* statement nl* ")";
|
||||
|
||||
sep:alias = (";" | nl)+;
|
||||
statement-list:alias = statement (sep statement)*;
|
||||
|
||||
shebang-command = [^\n]*;
|
||||
shebang = "#!" shebang-command "\n";
|
||||
mml:root = shebang? sep? statement-list? sep?;
|
@ -4,12 +4,12 @@ package treerack
|
||||
// only to the source code generated with treerack.
|
||||
const gendoc = `
|
||||
/*
|
||||
This file was generated with treerack (https://code.squareroundforest.org/arpio/treerack).
|
||||
This file was generated with 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://code.squareroundforest.org/arpio/treerack),
|
||||
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.
|
||||
|
||||
|
10
go.mod
10
go.mod
@ -1,10 +0,0 @@
|
||||
module code.squareroundforest.org/arpio/treerack
|
||||
|
||||
go 1.24.6
|
||||
|
||||
require golang.org/x/crypto v0.41.0
|
||||
|
||||
require (
|
||||
golang.org/x/sys v0.35.0 // indirect
|
||||
golang.org/x/term v0.34.0 // indirect
|
||||
)
|
6
go.sum
6
go.sum
@ -1,6 +0,0 @@
|
||||
golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4=
|
||||
golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc=
|
||||
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
|
||||
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4=
|
||||
golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw=
|
@ -1,23 +0,0 @@
|
||||
package treerack
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestKeyword(t *testing.T) {
|
||||
const syntax = `
|
||||
keywords:kw = "foo" | "bar";
|
||||
symbol:nokw = [a-z]+;
|
||||
`
|
||||
|
||||
runTests(t, syntax, []testItem{{
|
||||
title: "keyword",
|
||||
text: "foo",
|
||||
fail: true,
|
||||
}, {
|
||||
title: "not keyword",
|
||||
text: "baz",
|
||||
ignorePosition: true,
|
||||
node: &Node{
|
||||
Name: "symbol",
|
||||
},
|
||||
}})
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
package treerack
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMMLExp2(t *testing.T) {
|
||||
s, err := openSyntaxFile("examples/mml-exp2.treerack")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
t.Run("indexer", func(t *testing.T) {
|
||||
runTestsSyntax(t, s, []testItem{{
|
||||
title: "mixed indexer",
|
||||
text: "a.b[c]",
|
||||
ignorePosition: true,
|
||||
nodes: []*Node{{
|
||||
Name: "indexer",
|
||||
Nodes: []*Node{{
|
||||
Name: "symbol",
|
||||
}, {
|
||||
Name: "symbol-index",
|
||||
Nodes: []*Node{{
|
||||
Name: "symbol",
|
||||
}},
|
||||
}, {
|
||||
Name: "expression-index",
|
||||
Nodes: []*Node{{
|
||||
Name: "symbol",
|
||||
}},
|
||||
}},
|
||||
}},
|
||||
}})
|
||||
|
||||
runTestsSyntax(t, s, []testItem{{
|
||||
title: "mixed indexer inverted",
|
||||
text: "a[b].c",
|
||||
ignorePosition: true,
|
||||
nodes: []*Node{{
|
||||
Name: "indexer",
|
||||
Nodes: []*Node{{
|
||||
Name: "symbol",
|
||||
}, {
|
||||
Name: "expression-index",
|
||||
Nodes: []*Node{{
|
||||
Name: "symbol",
|
||||
}},
|
||||
}, {
|
||||
Name: "symbol-index",
|
||||
Nodes: []*Node{{
|
||||
Name: "symbol",
|
||||
}},
|
||||
}},
|
||||
}},
|
||||
}})
|
||||
})
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
package treerack
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMMLExp3(t *testing.T) {
|
||||
s, err := openSyntaxFile("examples/mml-exp3.treerack")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
t.Run("indexer", func(t *testing.T) {
|
||||
runTestsSyntax(t, s, []testItem{{
|
||||
title: "assignment",
|
||||
text: "fn f() a.b = c",
|
||||
ignorePosition: true,
|
||||
nodes: []*Node{{
|
||||
Name: "function-definition",
|
||||
Nodes: []*Node{{
|
||||
Name: "function-capture",
|
||||
Nodes: []*Node{{
|
||||
Name: "symbol",
|
||||
}, {
|
||||
Name: "assignment",
|
||||
Nodes: []*Node{{
|
||||
Name: "indexer",
|
||||
Nodes: []*Node{{
|
||||
Name: "symbol",
|
||||
}, {
|
||||
Name: "symbol-index",
|
||||
Nodes: []*Node{{
|
||||
Name: "symbol",
|
||||
}},
|
||||
}},
|
||||
}, {
|
||||
Name: "symbol",
|
||||
}},
|
||||
}},
|
||||
}},
|
||||
}},
|
||||
}})
|
||||
})
|
||||
}
|
2
node.go
2
node.go
@ -1,6 +1,6 @@
|
||||
package treerack
|
||||
|
||||
import "code.squareroundforest.org/arpio/treerack/self"
|
||||
import "github.com/aryszka/treerack/self"
|
||||
|
||||
func mapNodes(m func(n *Node) *Node, n []*Node) []*Node {
|
||||
var nn []*Node
|
||||
|
@ -742,7 +742,7 @@ func TestCharBuildNoop(t *testing.T) {
|
||||
c := newChar("foo", false, nil, nil)
|
||||
c.init(newRegistry())
|
||||
b := c.builder()
|
||||
ctx := newContext(bufio.NewReader(bytes.NewBuffer(nil)), nil)
|
||||
ctx := newContext(bufio.NewReader(bytes.NewBuffer(nil)))
|
||||
if n, ok := b.build(ctx); len(n) != 0 || ok {
|
||||
t.Error("char build not noop")
|
||||
}
|
||||
|
542
self/self.go
542
self/self.go
@ -1,10 +1,10 @@
|
||||
/*
|
||||
This file was generated with treerack (https://code.squareroundforest.org/arpio/treerack).
|
||||
This file was generated with 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://code.squareroundforest.org/arpio/treerack),
|
||||
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.
|
||||
|
||||
@ -137,17 +137,6 @@ func (p *sequenceParser) parse(c *context) {
|
||||
currentCount = 0
|
||||
continue
|
||||
}
|
||||
c.offset = from
|
||||
if c.fromResults(p) {
|
||||
if to > c.failOffset {
|
||||
c.failOffset = -1
|
||||
c.failingParser = nil
|
||||
}
|
||||
if !p.allChars {
|
||||
c.results.unmarkPending(from, p.id)
|
||||
}
|
||||
return
|
||||
}
|
||||
if c.failingParser == nil && p.commit&userDefined != 0 && p.commit&Whitespace == 0 && p.commit&FailPass == 0 {
|
||||
c.failingParser = p
|
||||
}
|
||||
@ -167,16 +156,6 @@ func (p *sequenceParser) parse(c *context) {
|
||||
currentCount = 0
|
||||
}
|
||||
}
|
||||
if p.commit&NoKeyword != 0 && c.isKeyword(from, to) {
|
||||
if c.failingParser == nil && p.commit&userDefined != 0 && p.commit&Whitespace == 0 && p.commit&FailPass == 0 {
|
||||
c.failingParser = p
|
||||
}
|
||||
c.fail(from)
|
||||
if !p.allChars {
|
||||
c.results.unmarkPending(from, p.id)
|
||||
}
|
||||
return
|
||||
}
|
||||
for _, g := range p.generalizations {
|
||||
if c.results.pending(from, g) {
|
||||
c.results.setMatch(from, g, to)
|
||||
@ -338,14 +317,6 @@ func (p *choiceParser) parse(c *context) {
|
||||
}
|
||||
}
|
||||
if match {
|
||||
if p.commit&NoKeyword != 0 && c.isKeyword(from, to) {
|
||||
if c.failingParser == nil && p.commit&userDefined != 0 && p.commit&Whitespace == 0 && p.commit&FailPass == 0 {
|
||||
c.failingParser = p
|
||||
}
|
||||
c.fail(from)
|
||||
c.results.unmarkPending(from, p.id)
|
||||
return
|
||||
}
|
||||
if failOffset > to {
|
||||
c.failOffset = failOffset
|
||||
c.failingParser = failingParser
|
||||
@ -595,11 +566,9 @@ func (r *results) unmarkPending(offset, id int) {
|
||||
|
||||
type context struct {
|
||||
reader io.RuneReader
|
||||
keywords []parser
|
||||
offset int
|
||||
readOffset int
|
||||
consumed int
|
||||
offsetLimit int
|
||||
failOffset int
|
||||
failingParser parser
|
||||
readErr error
|
||||
@ -609,8 +578,8 @@ type context struct {
|
||||
matchLast bool
|
||||
}
|
||||
|
||||
func newContext(r io.RuneReader, keywords []parser) *context {
|
||||
return &context{reader: r, keywords: keywords, results: &results{}, offsetLimit: -1, failOffset: -1}
|
||||
func newContext(r io.RuneReader) *context {
|
||||
return &context{reader: r, results: &results{}, failOffset: -1}
|
||||
}
|
||||
func (c *context) read() bool {
|
||||
if c.eof || c.readErr != nil {
|
||||
@ -637,9 +606,6 @@ func (c *context) read() bool {
|
||||
return true
|
||||
}
|
||||
func (c *context) token() (rune, bool) {
|
||||
if c.offset == c.offsetLimit {
|
||||
return 0, false
|
||||
}
|
||||
if c.offset == c.readOffset {
|
||||
if !c.read() {
|
||||
return 0, false
|
||||
@ -659,21 +625,6 @@ func (c *context) fromResults(p parser) bool {
|
||||
}
|
||||
return true
|
||||
}
|
||||
func (c *context) isKeyword(from, to int) bool {
|
||||
ol := c.offsetLimit
|
||||
c.offsetLimit = to
|
||||
defer func() {
|
||||
c.offsetLimit = ol
|
||||
}()
|
||||
for _, kw := range c.keywords {
|
||||
c.offset = from
|
||||
kw.parse(c)
|
||||
if c.matchLast && c.offset == to {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
func (c *context) success(to int) {
|
||||
c.offset = to
|
||||
c.matchLast = true
|
||||
@ -751,8 +702,6 @@ const (
|
||||
Alias CommitType = 1 << iota
|
||||
Whitespace
|
||||
NoWhitespace
|
||||
Keyword
|
||||
NoKeyword
|
||||
FailPass
|
||||
Root
|
||||
userDefined
|
||||
@ -790,8 +739,8 @@ 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 parseInput(r io.Reader, p parser, b builder, kw []parser) (*Node, error) {
|
||||
c := newContext(bufio.NewReader(r), kw)
|
||||
func parseInput(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
|
||||
@ -809,36 +758,35 @@ func parseInput(r io.Reader, p parser, b builder, kw []parser) (*Node, error) {
|
||||
}
|
||||
|
||||
func Parse(r io.Reader) (*Node, error) {
|
||||
|
||||
var p196 = sequenceParser{id: 196, commit: 128, ranges: [][]int{{0, -1}, {1, 1}, {0, -1}}}
|
||||
var p194 = choiceParser{id: 194, commit: 2}
|
||||
var p193 = choiceParser{id: 193, commit: 262, name: "wsc", generalizations: []int{194}}
|
||||
var p15 = choiceParser{id: 15, commit: 258, name: "wschar", generalizations: []int{193, 194}}
|
||||
var p2 = sequenceParser{id: 2, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{15, 193, 194}}
|
||||
var p188 = sequenceParser{id: 188, commit: 32, ranges: [][]int{{0, -1}, {1, 1}, {0, -1}}}
|
||||
var p186 = choiceParser{id: 186, commit: 2}
|
||||
var p185 = choiceParser{id: 185, commit: 70, name: "wsc", generalizations: []int{186}}
|
||||
var p15 = choiceParser{id: 15, commit: 66, name: "wschar", generalizations: []int{185, 186}}
|
||||
var p2 = sequenceParser{id: 2, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{15, 185, 186}}
|
||||
var p1 = charParser{id: 1, chars: []rune{32}}
|
||||
p2.items = []parser{&p1}
|
||||
var p4 = sequenceParser{id: 4, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{15, 193, 194}}
|
||||
var p4 = sequenceParser{id: 4, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{15, 185, 186}}
|
||||
var p3 = charParser{id: 3, chars: []rune{9}}
|
||||
p4.items = []parser{&p3}
|
||||
var p6 = sequenceParser{id: 6, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{15, 193, 194}}
|
||||
var p6 = sequenceParser{id: 6, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{15, 185, 186}}
|
||||
var p5 = charParser{id: 5, chars: []rune{10}}
|
||||
p6.items = []parser{&p5}
|
||||
var p8 = sequenceParser{id: 8, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{15, 193, 194}}
|
||||
var p8 = sequenceParser{id: 8, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{15, 185, 186}}
|
||||
var p7 = charParser{id: 7, chars: []rune{8}}
|
||||
p8.items = []parser{&p7}
|
||||
var p10 = sequenceParser{id: 10, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{15, 193, 194}}
|
||||
var p10 = sequenceParser{id: 10, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{15, 185, 186}}
|
||||
var p9 = charParser{id: 9, chars: []rune{12}}
|
||||
p10.items = []parser{&p9}
|
||||
var p12 = sequenceParser{id: 12, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{15, 193, 194}}
|
||||
var p12 = sequenceParser{id: 12, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{15, 185, 186}}
|
||||
var p11 = charParser{id: 11, chars: []rune{13}}
|
||||
p12.items = []parser{&p11}
|
||||
var p14 = sequenceParser{id: 14, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{15, 193, 194}}
|
||||
var p14 = sequenceParser{id: 14, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{15, 185, 186}}
|
||||
var p13 = charParser{id: 13, chars: []rune{11}}
|
||||
p14.items = []parser{&p13}
|
||||
p15.options = []parser{&p2, &p4, &p6, &p8, &p10, &p12, &p14}
|
||||
var p54 = sequenceParser{id: 54, commit: 264, name: "comment", ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {0, -1}}, generalizations: []int{193, 194}}
|
||||
var p37 = choiceParser{id: 37, commit: 266, name: "comment-segment"}
|
||||
var p36 = sequenceParser{id: 36, commit: 266, name: "line-comment", ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {0, -1}}, generalizations: []int{37}}
|
||||
var p54 = sequenceParser{id: 54, commit: 72, name: "comment", ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {0, -1}}, generalizations: []int{185, 186}}
|
||||
var p37 = choiceParser{id: 37, commit: 74, name: "comment-segment"}
|
||||
var p36 = sequenceParser{id: 36, commit: 74, name: "line-comment", ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {0, -1}}, generalizations: []int{37}}
|
||||
var p33 = sequenceParser{id: 33, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}}}
|
||||
var p31 = charParser{id: 31, chars: []rune{47}}
|
||||
var p32 = charParser{id: 32, chars: []rune{47}}
|
||||
@ -847,7 +795,7 @@ func Parse(r io.Reader) (*Node, error) {
|
||||
var p34 = charParser{id: 34, not: true, chars: []rune{10}}
|
||||
p35.items = []parser{&p34}
|
||||
p36.items = []parser{&p33, &p35}
|
||||
var p30 = sequenceParser{id: 30, commit: 266, name: "block-comment", ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {1, 1}, {0, -1}, {1, 1}}, generalizations: []int{37}}
|
||||
var p30 = sequenceParser{id: 30, commit: 74, name: "block-comment", ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {1, 1}, {0, -1}, {1, 1}}, generalizations: []int{37}}
|
||||
var p18 = sequenceParser{id: 18, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}}}
|
||||
var p16 = charParser{id: 16, chars: []rune{47}}
|
||||
var p17 = charParser{id: 17, chars: []rune{42}}
|
||||
@ -872,7 +820,7 @@ func Parse(r io.Reader) (*Node, error) {
|
||||
p30.items = []parser{&p18, &p26, &p29}
|
||||
p37.options = []parser{&p36, &p30}
|
||||
var p53 = sequenceParser{id: 53, commit: 10, ranges: [][]int{{0, -1}, {0, 1}, {0, -1}, {1, 1}, {0, -1}, {0, 1}, {0, -1}, {1, 1}}}
|
||||
var p50 = choiceParser{id: 50, commit: 266, name: "ws-no-nl"}
|
||||
var p50 = choiceParser{id: 50, commit: 74, name: "ws-no-nl"}
|
||||
var p39 = sequenceParser{id: 39, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{50}}
|
||||
var p38 = charParser{id: 38, chars: []rune{32}}
|
||||
p39.items = []parser{&p38}
|
||||
@ -897,92 +845,82 @@ func Parse(r io.Reader) (*Node, error) {
|
||||
p52.items = []parser{&p51}
|
||||
p53.items = []parser{&p50, &p52, &p50, &p37}
|
||||
p54.items = []parser{&p37, &p53}
|
||||
p193.options = []parser{&p15, &p54}
|
||||
p194.options = []parser{&p193}
|
||||
var p195 = sequenceParser{id: 195, commit: 258, name: "syntax:wsroot", ranges: [][]int{{0, 1}, {0, -1}, {0, 1}, {0, 1}}}
|
||||
var p190 = sequenceParser{id: 190, commit: 2, ranges: [][]int{{1, 1}, {0, -1}}}
|
||||
var p186 = sequenceParser{id: 186, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var p185 = charParser{id: 185, chars: []rune{59}}
|
||||
p186.items = []parser{&p185}
|
||||
var p189 = sequenceParser{id: 189, commit: 2, ranges: [][]int{{0, -1}, {1, 1}}}
|
||||
p189.items = []parser{&p194, &p186}
|
||||
p190.items = []parser{&p186, &p189}
|
||||
var p184 = sequenceParser{id: 184, commit: 258, name: "definitions", ranges: [][]int{{1, 1}, {0, 1}}}
|
||||
var p177 = sequenceParser{id: 177, commit: 256, name: "definition", ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {0, -1}, {1, 1}}}
|
||||
var p174 = sequenceParser{id: 174, commit: 266, name: "definition-name", ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {0, -1}}}
|
||||
var p92 = sequenceParser{id: 92, commit: 264, name: "symbol", ranges: [][]int{{1, -1}, {1, -1}}, generalizations: []int{133, 123, 127}}
|
||||
p185.options = []parser{&p15, &p54}
|
||||
p186.options = []parser{&p185}
|
||||
var p187 = sequenceParser{id: 187, commit: 66, name: "syntax:wsroot", ranges: [][]int{{0, 1}, {0, -1}, {0, 1}, {0, 1}}}
|
||||
var p182 = sequenceParser{id: 182, commit: 2, ranges: [][]int{{1, 1}, {0, -1}}}
|
||||
var p178 = sequenceParser{id: 178, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var p177 = charParser{id: 177, chars: []rune{59}}
|
||||
p178.items = []parser{&p177}
|
||||
var p181 = sequenceParser{id: 181, commit: 2, ranges: [][]int{{0, -1}, {1, 1}}}
|
||||
p181.items = []parser{&p186, &p178}
|
||||
p182.items = []parser{&p178, &p181}
|
||||
var p176 = sequenceParser{id: 176, commit: 66, name: "definitions", ranges: [][]int{{1, 1}, {0, 1}}}
|
||||
var p169 = sequenceParser{id: 169, commit: 64, name: "definition", ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {0, -1}, {1, 1}}}
|
||||
var p166 = sequenceParser{id: 166, commit: 74, name: "definition-name", ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {0, -1}}}
|
||||
var p92 = sequenceParser{id: 92, commit: 72, name: "symbol", ranges: [][]int{{1, -1}, {1, -1}}, generalizations: []int{133, 123, 127}}
|
||||
var p91 = sequenceParser{id: 91, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var p90 = charParser{id: 90, 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}}
|
||||
p91.items = []parser{&p90}
|
||||
p92.items = []parser{&p91}
|
||||
var p173 = sequenceParser{id: 173, commit: 10, ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}}}
|
||||
var p172 = sequenceParser{id: 172, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var p171 = charParser{id: 171, chars: []rune{58}}
|
||||
p172.items = []parser{&p171}
|
||||
var p170 = choiceParser{id: 170, commit: 258, name: "flag"}
|
||||
var p139 = sequenceParser{id: 139, commit: 264, name: "alias", allChars: true, ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}}, generalizations: []int{170}}
|
||||
var p165 = sequenceParser{id: 165, commit: 10, ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}}}
|
||||
var p164 = sequenceParser{id: 164, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var p163 = charParser{id: 163, chars: []rune{58}}
|
||||
p164.items = []parser{&p163}
|
||||
var p162 = choiceParser{id: 162, commit: 66, name: "flag"}
|
||||
var p139 = sequenceParser{id: 139, commit: 72, name: "alias", allChars: true, ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}}, generalizations: []int{162}}
|
||||
var p134 = charParser{id: 134, chars: []rune{97}}
|
||||
var p135 = charParser{id: 135, chars: []rune{108}}
|
||||
var p136 = charParser{id: 136, chars: []rune{105}}
|
||||
var p137 = charParser{id: 137, chars: []rune{97}}
|
||||
var p138 = charParser{id: 138, chars: []rune{115}}
|
||||
p139.items = []parser{&p134, &p135, &p136, &p137, &p138}
|
||||
var p142 = sequenceParser{id: 142, commit: 264, name: "ws", allChars: true, ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}}, generalizations: []int{170}}
|
||||
var p142 = sequenceParser{id: 142, commit: 72, name: "ws", allChars: true, ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}}, generalizations: []int{162}}
|
||||
var p140 = charParser{id: 140, chars: []rune{119}}
|
||||
var p141 = charParser{id: 141, chars: []rune{115}}
|
||||
p142.items = []parser{&p140, &p141}
|
||||
var p147 = sequenceParser{id: 147, commit: 264, name: "nows", allChars: true, ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}}, generalizations: []int{170}}
|
||||
var p147 = sequenceParser{id: 147, commit: 72, name: "nows", allChars: true, ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}}, generalizations: []int{162}}
|
||||
var p143 = charParser{id: 143, chars: []rune{110}}
|
||||
var p144 = charParser{id: 144, chars: []rune{111}}
|
||||
var p145 = charParser{id: 145, chars: []rune{119}}
|
||||
var p146 = charParser{id: 146, chars: []rune{115}}
|
||||
p147.items = []parser{&p143, &p144, &p145, &p146}
|
||||
var p150 = sequenceParser{id: 150, commit: 264, name: "kw", allChars: true, ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}}, generalizations: []int{170}}
|
||||
var p148 = charParser{id: 148, chars: []rune{107}}
|
||||
var p149 = charParser{id: 149, chars: []rune{119}}
|
||||
p150.items = []parser{&p148, &p149}
|
||||
var p155 = sequenceParser{id: 155, commit: 264, name: "nokw", allChars: true, ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}}, generalizations: []int{170}}
|
||||
var p151 = charParser{id: 151, chars: []rune{110}}
|
||||
var p152 = charParser{id: 152, chars: []rune{111}}
|
||||
var p153 = charParser{id: 153, chars: []rune{107}}
|
||||
var p154 = charParser{id: 154, chars: []rune{119}}
|
||||
p155.items = []parser{&p151, &p152, &p153, &p154}
|
||||
var p164 = sequenceParser{id: 164, commit: 264, name: "failpass", allChars: true, 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{170}}
|
||||
var p156 = charParser{id: 156, chars: []rune{102}}
|
||||
var p157 = charParser{id: 157, chars: []rune{97}}
|
||||
var p158 = charParser{id: 158, chars: []rune{105}}
|
||||
var p159 = charParser{id: 159, chars: []rune{108}}
|
||||
var p160 = charParser{id: 160, chars: []rune{112}}
|
||||
var p161 = charParser{id: 161, chars: []rune{97}}
|
||||
var p162 = charParser{id: 162, chars: []rune{115}}
|
||||
var p163 = charParser{id: 163, chars: []rune{115}}
|
||||
p164.items = []parser{&p156, &p157, &p158, &p159, &p160, &p161, &p162, &p163}
|
||||
var p169 = sequenceParser{id: 169, commit: 264, name: "root", allChars: true, ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}}, generalizations: []int{170}}
|
||||
var p165 = charParser{id: 165, chars: []rune{114}}
|
||||
var p166 = charParser{id: 166, chars: []rune{111}}
|
||||
var p167 = charParser{id: 167, chars: []rune{111}}
|
||||
var p168 = charParser{id: 168, chars: []rune{116}}
|
||||
p169.items = []parser{&p165, &p166, &p167, &p168}
|
||||
p170.options = []parser{&p139, &p142, &p147, &p150, &p155, &p164, &p169}
|
||||
p173.items = []parser{&p172, &p170}
|
||||
p174.items = []parser{&p92, &p173}
|
||||
var p176 = sequenceParser{id: 176, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var p175 = charParser{id: 175, chars: []rune{61}}
|
||||
p176.items = []parser{&p175}
|
||||
var p133 = choiceParser{id: 133, commit: 258, name: "expression"}
|
||||
var p89 = choiceParser{id: 89, commit: 258, name: "terminal", generalizations: []int{133, 123, 127}}
|
||||
var p56 = sequenceParser{id: 56, commit: 264, name: "any-char", allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{89, 133, 123, 127}}
|
||||
var p156 = sequenceParser{id: 156, commit: 72, name: "failpass", allChars: true, 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{162}}
|
||||
var p148 = charParser{id: 148, chars: []rune{102}}
|
||||
var p149 = charParser{id: 149, chars: []rune{97}}
|
||||
var p150 = charParser{id: 150, chars: []rune{105}}
|
||||
var p151 = charParser{id: 151, chars: []rune{108}}
|
||||
var p152 = charParser{id: 152, chars: []rune{112}}
|
||||
var p153 = charParser{id: 153, chars: []rune{97}}
|
||||
var p154 = charParser{id: 154, chars: []rune{115}}
|
||||
var p155 = charParser{id: 155, chars: []rune{115}}
|
||||
p156.items = []parser{&p148, &p149, &p150, &p151, &p152, &p153, &p154, &p155}
|
||||
var p161 = sequenceParser{id: 161, commit: 72, name: "root", allChars: true, ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}}, generalizations: []int{162}}
|
||||
var p157 = charParser{id: 157, chars: []rune{114}}
|
||||
var p158 = charParser{id: 158, chars: []rune{111}}
|
||||
var p159 = charParser{id: 159, chars: []rune{111}}
|
||||
var p160 = charParser{id: 160, chars: []rune{116}}
|
||||
p161.items = []parser{&p157, &p158, &p159, &p160}
|
||||
p162.options = []parser{&p139, &p142, &p147, &p156, &p161}
|
||||
p165.items = []parser{&p164, &p162}
|
||||
p166.items = []parser{&p92, &p165}
|
||||
var p168 = sequenceParser{id: 168, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var p167 = charParser{id: 167, chars: []rune{61}}
|
||||
p168.items = []parser{&p167}
|
||||
var p133 = choiceParser{id: 133, commit: 66, name: "expression"}
|
||||
var p89 = choiceParser{id: 89, commit: 66, name: "terminal", generalizations: []int{133, 123, 127}}
|
||||
var p56 = sequenceParser{id: 56, commit: 72, name: "any-char", allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{89, 133, 123, 127}}
|
||||
var p55 = charParser{id: 55, chars: []rune{46}}
|
||||
p56.items = []parser{&p55}
|
||||
var p75 = sequenceParser{id: 75, commit: 264, name: "char-class", ranges: [][]int{{1, 1}, {0, 1}, {0, -1}, {1, 1}, {1, 1}, {0, 1}, {0, -1}, {1, 1}}, generalizations: []int{89, 133, 123, 127}}
|
||||
var p75 = sequenceParser{id: 75, commit: 72, name: "char-class", ranges: [][]int{{1, 1}, {0, 1}, {0, -1}, {1, 1}, {1, 1}, {0, 1}, {0, -1}, {1, 1}}, generalizations: []int{89, 133, 123, 127}}
|
||||
var p71 = sequenceParser{id: 71, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var p70 = charParser{id: 70, chars: []rune{91}}
|
||||
p71.items = []parser{&p70}
|
||||
var p58 = sequenceParser{id: 58, commit: 264, name: "class-not", allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var p58 = sequenceParser{id: 58, commit: 72, name: "class-not", allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var p57 = charParser{id: 57, chars: []rune{94}}
|
||||
p58.items = []parser{&p57}
|
||||
var p72 = choiceParser{id: 72, commit: 10}
|
||||
var p66 = choiceParser{id: 66, commit: 264, name: "class-char", generalizations: []int{72}}
|
||||
var p66 = choiceParser{id: 66, commit: 72, name: "class-char", generalizations: []int{72}}
|
||||
var p60 = sequenceParser{id: 60, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{66, 72}}
|
||||
var p59 = charParser{id: 59, not: true, chars: []rune{92, 91, 93, 94, 45}}
|
||||
p60.items = []parser{&p59}
|
||||
@ -995,7 +933,7 @@ func Parse(r io.Reader) (*Node, error) {
|
||||
p64.items = []parser{&p63}
|
||||
p65.items = []parser{&p62, &p64}
|
||||
p66.options = []parser{&p60, &p65}
|
||||
var p69 = sequenceParser{id: 69, commit: 264, name: "char-range", ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}}, generalizations: []int{72}}
|
||||
var p69 = sequenceParser{id: 69, commit: 72, name: "char-range", ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}}, generalizations: []int{72}}
|
||||
var p68 = sequenceParser{id: 68, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var p67 = charParser{id: 67, chars: []rune{45}}
|
||||
p68.items = []parser{&p67}
|
||||
@ -1005,11 +943,11 @@ func Parse(r io.Reader) (*Node, error) {
|
||||
var p73 = charParser{id: 73, chars: []rune{93}}
|
||||
p74.items = []parser{&p73}
|
||||
p75.items = []parser{&p71, &p58, &p72, &p74}
|
||||
var p88 = sequenceParser{id: 88, commit: 264, name: "char-sequence", ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {1, 1}, {0, -1}, {1, 1}}, generalizations: []int{89, 133, 123, 127}}
|
||||
var p88 = sequenceParser{id: 88, commit: 72, name: "char-sequence", ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {1, 1}, {0, -1}, {1, 1}}, generalizations: []int{89, 133, 123, 127}}
|
||||
var p85 = sequenceParser{id: 85, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var p84 = charParser{id: 84, chars: []rune{34}}
|
||||
p85.items = []parser{&p84}
|
||||
var p83 = choiceParser{id: 83, commit: 264, name: "sequence-char"}
|
||||
var p83 = choiceParser{id: 83, commit: 72, name: "sequence-char"}
|
||||
var p77 = sequenceParser{id: 77, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{83}}
|
||||
var p76 = charParser{id: 76, not: true, chars: []rune{92, 34}}
|
||||
p77.items = []parser{&p76}
|
||||
@ -1027,25 +965,25 @@ func Parse(r io.Reader) (*Node, error) {
|
||||
p87.items = []parser{&p86}
|
||||
p88.items = []parser{&p85, &p83, &p87}
|
||||
p89.options = []parser{&p56, &p75, &p88}
|
||||
var p97 = sequenceParser{id: 97, commit: 258, name: "group", ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {0, -1}, {1, 1}}, generalizations: []int{133, 123, 127}}
|
||||
var p97 = sequenceParser{id: 97, commit: 66, name: "group", ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {0, -1}, {1, 1}}, generalizations: []int{133, 123, 127}}
|
||||
var p94 = sequenceParser{id: 94, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var p93 = charParser{id: 93, chars: []rune{40}}
|
||||
p94.items = []parser{&p93}
|
||||
var p96 = sequenceParser{id: 96, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var p95 = charParser{id: 95, chars: []rune{41}}
|
||||
p96.items = []parser{&p95}
|
||||
p97.items = []parser{&p94, &p194, &p133, &p194, &p96}
|
||||
var p126 = sequenceParser{id: 126, commit: 256, name: "sequence", ranges: [][]int{{1, 1}, {0, -1}}, generalizations: []int{133, 127}}
|
||||
var p124 = sequenceParser{id: 124, commit: 264, name: "item", ranges: [][]int{{1, 1}, {0, 1}, {1, 1}, {0, 1}}}
|
||||
p97.items = []parser{&p94, &p186, &p133, &p186, &p96}
|
||||
var p126 = sequenceParser{id: 126, commit: 64, name: "sequence", ranges: [][]int{{1, 1}, {0, -1}}, generalizations: []int{133, 127}}
|
||||
var p124 = sequenceParser{id: 124, commit: 72, name: "item", ranges: [][]int{{1, 1}, {0, 1}, {1, 1}, {0, 1}}}
|
||||
var p123 = choiceParser{id: 123, commit: 10}
|
||||
p123.options = []parser{&p89, &p92, &p97}
|
||||
var p122 = choiceParser{id: 122, commit: 258, name: "quantity"}
|
||||
var p106 = sequenceParser{id: 106, commit: 256, name: "count-quantifier", ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {0, -1}, {1, 1}}, generalizations: []int{122}}
|
||||
var p122 = choiceParser{id: 122, commit: 66, name: "quantity"}
|
||||
var p106 = sequenceParser{id: 106, commit: 64, name: "count-quantifier", ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {0, -1}, {1, 1}}, generalizations: []int{122}}
|
||||
var p103 = sequenceParser{id: 103, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var p102 = charParser{id: 102, chars: []rune{123}}
|
||||
p103.items = []parser{&p102}
|
||||
var p101 = sequenceParser{id: 101, commit: 256, name: "count", ranges: [][]int{{1, 1}}}
|
||||
var p100 = sequenceParser{id: 100, commit: 266, name: "number", ranges: [][]int{{1, -1}, {1, -1}}}
|
||||
var p101 = sequenceParser{id: 101, commit: 64, name: "count", ranges: [][]int{{1, 1}}}
|
||||
var p100 = sequenceParser{id: 100, commit: 74, name: "number", ranges: [][]int{{1, -1}, {1, -1}}}
|
||||
var p99 = sequenceParser{id: 99, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var p98 = charParser{id: 98, ranges: [][]rune{{48, 57}}}
|
||||
p99.items = []parser{&p98}
|
||||
@ -1054,99 +992,99 @@ func Parse(r io.Reader) (*Node, error) {
|
||||
var p105 = sequenceParser{id: 105, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var p104 = charParser{id: 104, chars: []rune{125}}
|
||||
p105.items = []parser{&p104}
|
||||
p106.items = []parser{&p103, &p194, &p101, &p194, &p105}
|
||||
var p115 = sequenceParser{id: 115, commit: 256, 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{122}}
|
||||
p106.items = []parser{&p103, &p186, &p101, &p186, &p105}
|
||||
var p115 = sequenceParser{id: 115, commit: 64, 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{122}}
|
||||
var p110 = sequenceParser{id: 110, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var p109 = charParser{id: 109, chars: []rune{123}}
|
||||
p110.items = []parser{&p109}
|
||||
var p107 = sequenceParser{id: 107, commit: 256, name: "range-from", ranges: [][]int{{1, 1}}}
|
||||
var p107 = sequenceParser{id: 107, commit: 64, name: "range-from", ranges: [][]int{{1, 1}}}
|
||||
p107.items = []parser{&p100}
|
||||
var p112 = sequenceParser{id: 112, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var p111 = charParser{id: 111, chars: []rune{44}}
|
||||
p112.items = []parser{&p111}
|
||||
var p108 = sequenceParser{id: 108, commit: 256, name: "range-to", ranges: [][]int{{1, 1}}}
|
||||
var p108 = sequenceParser{id: 108, commit: 64, name: "range-to", ranges: [][]int{{1, 1}}}
|
||||
p108.items = []parser{&p100}
|
||||
var p114 = sequenceParser{id: 114, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var p113 = charParser{id: 113, chars: []rune{125}}
|
||||
p114.items = []parser{&p113}
|
||||
p115.items = []parser{&p110, &p194, &p107, &p194, &p112, &p194, &p108, &p194, &p114}
|
||||
var p117 = sequenceParser{id: 117, commit: 264, name: "one-or-more", allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{122}}
|
||||
p115.items = []parser{&p110, &p186, &p107, &p186, &p112, &p186, &p108, &p186, &p114}
|
||||
var p117 = sequenceParser{id: 117, commit: 72, name: "one-or-more", allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{122}}
|
||||
var p116 = charParser{id: 116, chars: []rune{43}}
|
||||
p117.items = []parser{&p116}
|
||||
var p119 = sequenceParser{id: 119, commit: 264, name: "zero-or-more", allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{122}}
|
||||
var p119 = sequenceParser{id: 119, commit: 72, name: "zero-or-more", allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{122}}
|
||||
var p118 = charParser{id: 118, chars: []rune{42}}
|
||||
p119.items = []parser{&p118}
|
||||
var p121 = sequenceParser{id: 121, commit: 264, name: "zero-or-one", allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{122}}
|
||||
var p121 = sequenceParser{id: 121, commit: 72, name: "zero-or-one", allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{122}}
|
||||
var p120 = charParser{id: 120, chars: []rune{63}}
|
||||
p121.items = []parser{&p120}
|
||||
p122.options = []parser{&p106, &p115, &p117, &p119, &p121}
|
||||
p124.items = []parser{&p123, &p122}
|
||||
var p125 = sequenceParser{id: 125, commit: 2, ranges: [][]int{{0, -1}, {1, 1}}}
|
||||
p125.items = []parser{&p194, &p124}
|
||||
p125.items = []parser{&p186, &p124}
|
||||
p126.items = []parser{&p124, &p125}
|
||||
var p132 = sequenceParser{id: 132, commit: 256, name: "choice", ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {0, -1}}, generalizations: []int{133}}
|
||||
var p127 = choiceParser{id: 127, commit: 258, name: "option"}
|
||||
var p132 = sequenceParser{id: 132, commit: 64, name: "choice", ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {0, -1}}, generalizations: []int{133}}
|
||||
var p127 = choiceParser{id: 127, commit: 66, name: "option"}
|
||||
p127.options = []parser{&p89, &p92, &p97, &p126}
|
||||
var p130 = sequenceParser{id: 130, commit: 2, ranges: [][]int{{1, 1}, {0, -1}, {1, 1}}}
|
||||
var p129 = sequenceParser{id: 129, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var p128 = charParser{id: 128, chars: []rune{124}}
|
||||
p129.items = []parser{&p128}
|
||||
p130.items = []parser{&p129, &p194, &p127}
|
||||
p130.items = []parser{&p129, &p186, &p127}
|
||||
var p131 = sequenceParser{id: 131, commit: 2, ranges: [][]int{{0, -1}, {1, 1}}}
|
||||
p131.items = []parser{&p194, &p130}
|
||||
p132.items = []parser{&p127, &p194, &p130, &p131}
|
||||
p131.items = []parser{&p186, &p130}
|
||||
p132.items = []parser{&p127, &p186, &p130, &p131}
|
||||
p133.options = []parser{&p89, &p92, &p97, &p126, &p132}
|
||||
p177.items = []parser{&p174, &p194, &p176, &p194, &p133}
|
||||
var p183 = sequenceParser{id: 183, commit: 2, ranges: [][]int{{0, -1}, {1, 1}, {0, -1}}}
|
||||
var p181 = sequenceParser{id: 181, commit: 2, ranges: [][]int{{1, 1}, {0, -1}, {0, -1}, {1, 1}}}
|
||||
var p179 = sequenceParser{id: 179, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var p178 = charParser{id: 178, chars: []rune{59}}
|
||||
p179.items = []parser{&p178}
|
||||
var p180 = sequenceParser{id: 180, commit: 2, ranges: [][]int{{0, -1}, {1, 1}}}
|
||||
p180.items = []parser{&p194, &p179}
|
||||
p181.items = []parser{&p179, &p180, &p194, &p177}
|
||||
var p182 = sequenceParser{id: 182, commit: 2, ranges: [][]int{{0, -1}, {1, 1}}}
|
||||
p182.items = []parser{&p194, &p181}
|
||||
p183.items = []parser{&p194, &p181, &p182}
|
||||
p184.items = []parser{&p177, &p183}
|
||||
var p192 = sequenceParser{id: 192, commit: 2, ranges: [][]int{{0, -1}, {1, 1}, {0, -1}}}
|
||||
var p188 = sequenceParser{id: 188, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var p187 = charParser{id: 187, chars: []rune{59}}
|
||||
p188.items = []parser{&p187}
|
||||
var p191 = sequenceParser{id: 191, commit: 2, ranges: [][]int{{0, -1}, {1, 1}}}
|
||||
p191.items = []parser{&p194, &p188}
|
||||
p192.items = []parser{&p194, &p188, &p191}
|
||||
p195.items = []parser{&p190, &p194, &p184, &p192}
|
||||
p196.items = []parser{&p194, &p195, &p194}
|
||||
var b196 = sequenceBuilder{id: 196, commit: 128, name: "syntax", ranges: [][]int{{0, -1}, {1, 1}, {0, -1}}}
|
||||
var b194 = choiceBuilder{id: 194, commit: 2}
|
||||
var b193 = choiceBuilder{id: 193, commit: 262, generalizations: []int{194}}
|
||||
var b15 = choiceBuilder{id: 15, commit: 258, generalizations: []int{193, 194}}
|
||||
var b2 = sequenceBuilder{id: 2, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{15, 193, 194}}
|
||||
p169.items = []parser{&p166, &p186, &p168, &p186, &p133}
|
||||
var p175 = sequenceParser{id: 175, commit: 2, ranges: [][]int{{0, -1}, {1, 1}, {0, -1}}}
|
||||
var p173 = sequenceParser{id: 173, commit: 2, ranges: [][]int{{1, 1}, {0, -1}, {0, -1}, {1, 1}}}
|
||||
var p171 = sequenceParser{id: 171, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var p170 = charParser{id: 170, chars: []rune{59}}
|
||||
p171.items = []parser{&p170}
|
||||
var p172 = sequenceParser{id: 172, commit: 2, ranges: [][]int{{0, -1}, {1, 1}}}
|
||||
p172.items = []parser{&p186, &p171}
|
||||
p173.items = []parser{&p171, &p172, &p186, &p169}
|
||||
var p174 = sequenceParser{id: 174, commit: 2, ranges: [][]int{{0, -1}, {1, 1}}}
|
||||
p174.items = []parser{&p186, &p173}
|
||||
p175.items = []parser{&p186, &p173, &p174}
|
||||
p176.items = []parser{&p169, &p175}
|
||||
var p184 = sequenceParser{id: 184, commit: 2, ranges: [][]int{{0, -1}, {1, 1}, {0, -1}}}
|
||||
var p180 = sequenceParser{id: 180, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var p179 = charParser{id: 179, chars: []rune{59}}
|
||||
p180.items = []parser{&p179}
|
||||
var p183 = sequenceParser{id: 183, commit: 2, ranges: [][]int{{0, -1}, {1, 1}}}
|
||||
p183.items = []parser{&p186, &p180}
|
||||
p184.items = []parser{&p186, &p180, &p183}
|
||||
p187.items = []parser{&p182, &p186, &p176, &p184}
|
||||
p188.items = []parser{&p186, &p187, &p186}
|
||||
var b188 = sequenceBuilder{id: 188, commit: 32, 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 b15 = choiceBuilder{id: 15, commit: 66}
|
||||
var b2 = sequenceBuilder{id: 2, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var b1 = charBuilder{}
|
||||
b2.items = []builder{&b1}
|
||||
var b4 = sequenceBuilder{id: 4, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{15, 193, 194}}
|
||||
var b4 = sequenceBuilder{id: 4, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var b3 = charBuilder{}
|
||||
b4.items = []builder{&b3}
|
||||
var b6 = sequenceBuilder{id: 6, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{15, 193, 194}}
|
||||
var b6 = sequenceBuilder{id: 6, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var b5 = charBuilder{}
|
||||
b6.items = []builder{&b5}
|
||||
var b8 = sequenceBuilder{id: 8, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{15, 193, 194}}
|
||||
var b8 = sequenceBuilder{id: 8, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var b7 = charBuilder{}
|
||||
b8.items = []builder{&b7}
|
||||
var b10 = sequenceBuilder{id: 10, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{15, 193, 194}}
|
||||
var b10 = sequenceBuilder{id: 10, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var b9 = charBuilder{}
|
||||
b10.items = []builder{&b9}
|
||||
var b12 = sequenceBuilder{id: 12, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{15, 193, 194}}
|
||||
var b12 = sequenceBuilder{id: 12, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var b11 = charBuilder{}
|
||||
b12.items = []builder{&b11}
|
||||
var b14 = sequenceBuilder{id: 14, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{15, 193, 194}}
|
||||
var b14 = sequenceBuilder{id: 14, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var b13 = charBuilder{}
|
||||
b14.items = []builder{&b13}
|
||||
b15.options = []builder{&b2, &b4, &b6, &b8, &b10, &b12, &b14}
|
||||
var b54 = sequenceBuilder{id: 54, commit: 264, name: "comment", ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {0, -1}}, generalizations: []int{193, 194}}
|
||||
var b37 = choiceBuilder{id: 37, commit: 266}
|
||||
var b36 = sequenceBuilder{id: 36, commit: 266, ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {0, -1}}, generalizations: []int{37}}
|
||||
var b54 = sequenceBuilder{id: 54, commit: 72, name: "comment", ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {0, -1}}}
|
||||
var b37 = choiceBuilder{id: 37, commit: 74}
|
||||
var b36 = sequenceBuilder{id: 36, commit: 74, ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {0, -1}}}
|
||||
var b33 = sequenceBuilder{id: 33, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}}}
|
||||
var b31 = charBuilder{}
|
||||
var b32 = charBuilder{}
|
||||
@ -1155,13 +1093,13 @@ func Parse(r io.Reader) (*Node, error) {
|
||||
var b34 = charBuilder{}
|
||||
b35.items = []builder{&b34}
|
||||
b36.items = []builder{&b33, &b35}
|
||||
var b30 = sequenceBuilder{id: 30, commit: 266, ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {1, 1}, {0, -1}, {1, 1}}, generalizations: []int{37}}
|
||||
var b30 = sequenceBuilder{id: 30, commit: 74, ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {1, 1}, {0, -1}, {1, 1}}}
|
||||
var b18 = sequenceBuilder{id: 18, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}}}
|
||||
var b16 = charBuilder{}
|
||||
var b17 = charBuilder{}
|
||||
b18.items = []builder{&b16, &b17}
|
||||
var b26 = choiceBuilder{id: 26, commit: 10}
|
||||
var b23 = sequenceBuilder{id: 23, commit: 10, ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}}, generalizations: []int{26}}
|
||||
var b23 = sequenceBuilder{id: 23, commit: 10, ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}}}
|
||||
var b20 = sequenceBuilder{id: 20, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var b19 = charBuilder{}
|
||||
b20.items = []builder{&b19}
|
||||
@ -1169,7 +1107,7 @@ func Parse(r io.Reader) (*Node, error) {
|
||||
var b21 = charBuilder{}
|
||||
b22.items = []builder{&b21}
|
||||
b23.items = []builder{&b20, &b22}
|
||||
var b25 = sequenceBuilder{id: 25, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{26}}
|
||||
var b25 = sequenceBuilder{id: 25, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var b24 = charBuilder{}
|
||||
b25.items = []builder{&b24}
|
||||
b26.options = []builder{&b23, &b25}
|
||||
@ -1180,23 +1118,23 @@ func Parse(r io.Reader) (*Node, error) {
|
||||
b30.items = []builder{&b18, &b26, &b29}
|
||||
b37.options = []builder{&b36, &b30}
|
||||
var b53 = sequenceBuilder{id: 53, commit: 10, ranges: [][]int{{0, -1}, {0, 1}, {0, -1}, {1, 1}, {0, -1}, {0, 1}, {0, -1}, {1, 1}}}
|
||||
var b50 = choiceBuilder{id: 50, commit: 266}
|
||||
var b39 = sequenceBuilder{id: 39, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{50}}
|
||||
var b50 = choiceBuilder{id: 50, commit: 74}
|
||||
var b39 = sequenceBuilder{id: 39, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var b38 = charBuilder{}
|
||||
b39.items = []builder{&b38}
|
||||
var b41 = sequenceBuilder{id: 41, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{50}}
|
||||
var b41 = sequenceBuilder{id: 41, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var b40 = charBuilder{}
|
||||
b41.items = []builder{&b40}
|
||||
var b43 = sequenceBuilder{id: 43, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{50}}
|
||||
var b43 = sequenceBuilder{id: 43, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var b42 = charBuilder{}
|
||||
b43.items = []builder{&b42}
|
||||
var b45 = sequenceBuilder{id: 45, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{50}}
|
||||
var b45 = sequenceBuilder{id: 45, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var b44 = charBuilder{}
|
||||
b45.items = []builder{&b44}
|
||||
var b47 = sequenceBuilder{id: 47, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{50}}
|
||||
var b47 = sequenceBuilder{id: 47, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var b46 = charBuilder{}
|
||||
b47.items = []builder{&b46}
|
||||
var b49 = sequenceBuilder{id: 49, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{50}}
|
||||
var b49 = sequenceBuilder{id: 49, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var b48 = charBuilder{}
|
||||
b49.items = []builder{&b48}
|
||||
b50.options = []builder{&b39, &b41, &b43, &b45, &b47, &b49}
|
||||
@ -1205,96 +1143,86 @@ func Parse(r io.Reader) (*Node, error) {
|
||||
b52.items = []builder{&b51}
|
||||
b53.items = []builder{&b50, &b52, &b50, &b37}
|
||||
b54.items = []builder{&b37, &b53}
|
||||
b193.options = []builder{&b15, &b54}
|
||||
b194.options = []builder{&b193}
|
||||
var b195 = sequenceBuilder{id: 195, commit: 258, ranges: [][]int{{0, 1}, {0, -1}, {0, 1}, {0, 1}}}
|
||||
var b190 = sequenceBuilder{id: 190, commit: 2, ranges: [][]int{{1, 1}, {0, -1}}}
|
||||
var b186 = sequenceBuilder{id: 186, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var b185 = charBuilder{}
|
||||
b186.items = []builder{&b185}
|
||||
var b189 = sequenceBuilder{id: 189, commit: 2, ranges: [][]int{{0, -1}, {1, 1}}}
|
||||
b189.items = []builder{&b194, &b186}
|
||||
b190.items = []builder{&b186, &b189}
|
||||
var b184 = sequenceBuilder{id: 184, commit: 258, ranges: [][]int{{1, 1}, {0, 1}}}
|
||||
var b177 = sequenceBuilder{id: 177, commit: 256, name: "definition", ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {0, -1}, {1, 1}}}
|
||||
var b174 = sequenceBuilder{id: 174, commit: 266, ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {0, -1}}}
|
||||
var b92 = sequenceBuilder{id: 92, commit: 264, name: "symbol", ranges: [][]int{{1, -1}, {1, -1}}, generalizations: []int{133, 123, 127}}
|
||||
b185.options = []builder{&b15, &b54}
|
||||
b186.options = []builder{&b185}
|
||||
var b187 = sequenceBuilder{id: 187, commit: 66, ranges: [][]int{{0, 1}, {0, -1}, {0, 1}, {0, 1}}}
|
||||
var b182 = sequenceBuilder{id: 182, commit: 2, ranges: [][]int{{1, 1}, {0, -1}}}
|
||||
var b178 = sequenceBuilder{id: 178, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var b177 = charBuilder{}
|
||||
b178.items = []builder{&b177}
|
||||
var b181 = sequenceBuilder{id: 181, commit: 2, ranges: [][]int{{0, -1}, {1, 1}}}
|
||||
b181.items = []builder{&b186, &b178}
|
||||
b182.items = []builder{&b178, &b181}
|
||||
var b176 = sequenceBuilder{id: 176, commit: 66, ranges: [][]int{{1, 1}, {0, 1}}}
|
||||
var b169 = sequenceBuilder{id: 169, commit: 64, name: "definition", ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {0, -1}, {1, 1}}}
|
||||
var b166 = sequenceBuilder{id: 166, commit: 74, ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {0, -1}}}
|
||||
var b92 = sequenceBuilder{id: 92, commit: 72, name: "symbol", ranges: [][]int{{1, -1}, {1, -1}}}
|
||||
var b91 = sequenceBuilder{id: 91, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var b90 = charBuilder{}
|
||||
b91.items = []builder{&b90}
|
||||
b92.items = []builder{&b91}
|
||||
var b173 = sequenceBuilder{id: 173, commit: 10, ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}}}
|
||||
var b172 = sequenceBuilder{id: 172, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var b171 = charBuilder{}
|
||||
b172.items = []builder{&b171}
|
||||
var b170 = choiceBuilder{id: 170, commit: 258}
|
||||
var b139 = sequenceBuilder{id: 139, commit: 264, name: "alias", allChars: true, ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}}, generalizations: []int{170}}
|
||||
var b165 = sequenceBuilder{id: 165, commit: 10, ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}}}
|
||||
var b164 = sequenceBuilder{id: 164, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var b163 = charBuilder{}
|
||||
b164.items = []builder{&b163}
|
||||
var b162 = choiceBuilder{id: 162, commit: 66}
|
||||
var b139 = sequenceBuilder{id: 139, commit: 72, name: "alias", allChars: true, ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}}}
|
||||
var b134 = charBuilder{}
|
||||
var b135 = charBuilder{}
|
||||
var b136 = charBuilder{}
|
||||
var b137 = charBuilder{}
|
||||
var b138 = charBuilder{}
|
||||
b139.items = []builder{&b134, &b135, &b136, &b137, &b138}
|
||||
var b142 = sequenceBuilder{id: 142, commit: 264, name: "ws", allChars: true, ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}}, generalizations: []int{170}}
|
||||
var b142 = sequenceBuilder{id: 142, commit: 72, name: "ws", allChars: true, ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}}}
|
||||
var b140 = charBuilder{}
|
||||
var b141 = charBuilder{}
|
||||
b142.items = []builder{&b140, &b141}
|
||||
var b147 = sequenceBuilder{id: 147, commit: 264, name: "nows", allChars: true, ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}}, generalizations: []int{170}}
|
||||
var b147 = sequenceBuilder{id: 147, commit: 72, name: "nows", allChars: true, ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}}}
|
||||
var b143 = charBuilder{}
|
||||
var b144 = charBuilder{}
|
||||
var b145 = charBuilder{}
|
||||
var b146 = charBuilder{}
|
||||
b147.items = []builder{&b143, &b144, &b145, &b146}
|
||||
var b150 = sequenceBuilder{id: 150, commit: 264, name: "kw", allChars: true, ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}}, generalizations: []int{170}}
|
||||
var b156 = sequenceBuilder{id: 156, commit: 72, name: "failpass", allChars: true, 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 b148 = charBuilder{}
|
||||
var b149 = charBuilder{}
|
||||
b150.items = []builder{&b148, &b149}
|
||||
var b155 = sequenceBuilder{id: 155, commit: 264, name: "nokw", allChars: true, ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}}, generalizations: []int{170}}
|
||||
var b150 = charBuilder{}
|
||||
var b151 = charBuilder{}
|
||||
var b152 = charBuilder{}
|
||||
var b153 = charBuilder{}
|
||||
var b154 = charBuilder{}
|
||||
b155.items = []builder{&b151, &b152, &b153, &b154}
|
||||
var b164 = sequenceBuilder{id: 164, commit: 264, name: "failpass", allChars: true, 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{170}}
|
||||
var b156 = charBuilder{}
|
||||
var b155 = charBuilder{}
|
||||
b156.items = []builder{&b148, &b149, &b150, &b151, &b152, &b153, &b154, &b155}
|
||||
var b161 = sequenceBuilder{id: 161, commit: 72, name: "root", allChars: true, ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}}}
|
||||
var b157 = charBuilder{}
|
||||
var b158 = charBuilder{}
|
||||
var b159 = charBuilder{}
|
||||
var b160 = charBuilder{}
|
||||
var b161 = charBuilder{}
|
||||
var b162 = charBuilder{}
|
||||
var b163 = charBuilder{}
|
||||
b164.items = []builder{&b156, &b157, &b158, &b159, &b160, &b161, &b162, &b163}
|
||||
var b169 = sequenceBuilder{id: 169, commit: 264, name: "root", allChars: true, ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}}, generalizations: []int{170}}
|
||||
var b165 = charBuilder{}
|
||||
var b166 = charBuilder{}
|
||||
b161.items = []builder{&b157, &b158, &b159, &b160}
|
||||
b162.options = []builder{&b139, &b142, &b147, &b156, &b161}
|
||||
b165.items = []builder{&b164, &b162}
|
||||
b166.items = []builder{&b92, &b165}
|
||||
var b168 = sequenceBuilder{id: 168, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var b167 = charBuilder{}
|
||||
var b168 = charBuilder{}
|
||||
b169.items = []builder{&b165, &b166, &b167, &b168}
|
||||
b170.options = []builder{&b139, &b142, &b147, &b150, &b155, &b164, &b169}
|
||||
b173.items = []builder{&b172, &b170}
|
||||
b174.items = []builder{&b92, &b173}
|
||||
var b176 = sequenceBuilder{id: 176, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var b175 = charBuilder{}
|
||||
b176.items = []builder{&b175}
|
||||
var b133 = choiceBuilder{id: 133, commit: 258}
|
||||
var b89 = choiceBuilder{id: 89, commit: 258, generalizations: []int{133, 123, 127}}
|
||||
var b56 = sequenceBuilder{id: 56, commit: 264, name: "any-char", allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{89, 133, 123, 127}}
|
||||
b168.items = []builder{&b167}
|
||||
var b133 = choiceBuilder{id: 133, commit: 66}
|
||||
var b89 = choiceBuilder{id: 89, commit: 66}
|
||||
var b56 = sequenceBuilder{id: 56, commit: 72, name: "any-char", allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var b55 = charBuilder{}
|
||||
b56.items = []builder{&b55}
|
||||
var b75 = sequenceBuilder{id: 75, commit: 264, name: "char-class", ranges: [][]int{{1, 1}, {0, 1}, {0, -1}, {1, 1}, {1, 1}, {0, 1}, {0, -1}, {1, 1}}, generalizations: []int{89, 133, 123, 127}}
|
||||
var b75 = sequenceBuilder{id: 75, commit: 72, name: "char-class", ranges: [][]int{{1, 1}, {0, 1}, {0, -1}, {1, 1}, {1, 1}, {0, 1}, {0, -1}, {1, 1}}}
|
||||
var b71 = sequenceBuilder{id: 71, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var b70 = charBuilder{}
|
||||
b71.items = []builder{&b70}
|
||||
var b58 = sequenceBuilder{id: 58, commit: 264, name: "class-not", allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var b58 = sequenceBuilder{id: 58, commit: 72, name: "class-not", allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var b57 = charBuilder{}
|
||||
b58.items = []builder{&b57}
|
||||
var b72 = choiceBuilder{id: 72, commit: 10}
|
||||
var b66 = choiceBuilder{id: 66, commit: 264, name: "class-char", generalizations: []int{72}}
|
||||
var b60 = sequenceBuilder{id: 60, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{66, 72}}
|
||||
var b66 = choiceBuilder{id: 66, commit: 72, name: "class-char"}
|
||||
var b60 = sequenceBuilder{id: 60, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var b59 = charBuilder{}
|
||||
b60.items = []builder{&b59}
|
||||
var b65 = sequenceBuilder{id: 65, commit: 10, ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}}, generalizations: []int{66, 72}}
|
||||
var b65 = sequenceBuilder{id: 65, commit: 10, ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}}}
|
||||
var b62 = sequenceBuilder{id: 62, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var b61 = charBuilder{}
|
||||
b62.items = []builder{&b61}
|
||||
@ -1303,7 +1231,7 @@ func Parse(r io.Reader) (*Node, error) {
|
||||
b64.items = []builder{&b63}
|
||||
b65.items = []builder{&b62, &b64}
|
||||
b66.options = []builder{&b60, &b65}
|
||||
var b69 = sequenceBuilder{id: 69, commit: 264, name: "char-range", ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}}, generalizations: []int{72}}
|
||||
var b69 = sequenceBuilder{id: 69, commit: 72, name: "char-range", ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}}}
|
||||
var b68 = sequenceBuilder{id: 68, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var b67 = charBuilder{}
|
||||
b68.items = []builder{&b67}
|
||||
@ -1313,15 +1241,15 @@ func Parse(r io.Reader) (*Node, error) {
|
||||
var b73 = charBuilder{}
|
||||
b74.items = []builder{&b73}
|
||||
b75.items = []builder{&b71, &b58, &b72, &b74}
|
||||
var b88 = sequenceBuilder{id: 88, commit: 264, name: "char-sequence", ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {1, 1}, {0, -1}, {1, 1}}, generalizations: []int{89, 133, 123, 127}}
|
||||
var b88 = sequenceBuilder{id: 88, commit: 72, name: "char-sequence", ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {1, 1}, {0, -1}, {1, 1}}}
|
||||
var b85 = sequenceBuilder{id: 85, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var b84 = charBuilder{}
|
||||
b85.items = []builder{&b84}
|
||||
var b83 = choiceBuilder{id: 83, commit: 264, name: "sequence-char"}
|
||||
var b77 = sequenceBuilder{id: 77, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{83}}
|
||||
var b83 = choiceBuilder{id: 83, commit: 72, name: "sequence-char"}
|
||||
var b77 = sequenceBuilder{id: 77, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var b76 = charBuilder{}
|
||||
b77.items = []builder{&b76}
|
||||
var b82 = sequenceBuilder{id: 82, commit: 10, ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}}, generalizations: []int{83}}
|
||||
var b82 = sequenceBuilder{id: 82, commit: 10, ranges: [][]int{{1, 1}, {1, 1}, {1, 1}, {1, 1}}}
|
||||
var b79 = sequenceBuilder{id: 79, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var b78 = charBuilder{}
|
||||
b79.items = []builder{&b78}
|
||||
@ -1335,25 +1263,25 @@ func Parse(r io.Reader) (*Node, error) {
|
||||
b87.items = []builder{&b86}
|
||||
b88.items = []builder{&b85, &b83, &b87}
|
||||
b89.options = []builder{&b56, &b75, &b88}
|
||||
var b97 = sequenceBuilder{id: 97, commit: 258, ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {0, -1}, {1, 1}}, generalizations: []int{133, 123, 127}}
|
||||
var b97 = sequenceBuilder{id: 97, commit: 66, ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {0, -1}, {1, 1}}}
|
||||
var b94 = sequenceBuilder{id: 94, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var b93 = charBuilder{}
|
||||
b94.items = []builder{&b93}
|
||||
var b96 = sequenceBuilder{id: 96, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var b95 = charBuilder{}
|
||||
b96.items = []builder{&b95}
|
||||
b97.items = []builder{&b94, &b194, &b133, &b194, &b96}
|
||||
var b126 = sequenceBuilder{id: 126, commit: 256, name: "sequence", ranges: [][]int{{1, 1}, {0, -1}}, generalizations: []int{133, 127}}
|
||||
var b124 = sequenceBuilder{id: 124, commit: 264, name: "item", ranges: [][]int{{1, 1}, {0, 1}, {1, 1}, {0, 1}}}
|
||||
b97.items = []builder{&b94, &b186, &b133, &b186, &b96}
|
||||
var b126 = sequenceBuilder{id: 126, commit: 64, name: "sequence", ranges: [][]int{{1, 1}, {0, -1}}}
|
||||
var b124 = sequenceBuilder{id: 124, commit: 72, name: "item", ranges: [][]int{{1, 1}, {0, 1}, {1, 1}, {0, 1}}}
|
||||
var b123 = choiceBuilder{id: 123, commit: 10}
|
||||
b123.options = []builder{&b89, &b92, &b97}
|
||||
var b122 = choiceBuilder{id: 122, commit: 258}
|
||||
var b106 = sequenceBuilder{id: 106, commit: 256, name: "count-quantifier", ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {0, -1}, {1, 1}}, generalizations: []int{122}}
|
||||
var b122 = choiceBuilder{id: 122, commit: 66}
|
||||
var b106 = sequenceBuilder{id: 106, commit: 64, name: "count-quantifier", ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {0, -1}, {1, 1}}}
|
||||
var b103 = sequenceBuilder{id: 103, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var b102 = charBuilder{}
|
||||
b103.items = []builder{&b102}
|
||||
var b101 = sequenceBuilder{id: 101, commit: 256, name: "count", ranges: [][]int{{1, 1}}}
|
||||
var b100 = sequenceBuilder{id: 100, commit: 266, ranges: [][]int{{1, -1}, {1, -1}}}
|
||||
var b101 = sequenceBuilder{id: 101, commit: 64, name: "count", ranges: [][]int{{1, 1}}}
|
||||
var b100 = sequenceBuilder{id: 100, commit: 74, ranges: [][]int{{1, -1}, {1, -1}}}
|
||||
var b99 = sequenceBuilder{id: 99, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var b98 = charBuilder{}
|
||||
b99.items = []builder{&b98}
|
||||
@ -1362,72 +1290,70 @@ func Parse(r io.Reader) (*Node, error) {
|
||||
var b105 = sequenceBuilder{id: 105, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var b104 = charBuilder{}
|
||||
b105.items = []builder{&b104}
|
||||
b106.items = []builder{&b103, &b194, &b101, &b194, &b105}
|
||||
var b115 = sequenceBuilder{id: 115, commit: 256, 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{122}}
|
||||
b106.items = []builder{&b103, &b186, &b101, &b186, &b105}
|
||||
var b115 = sequenceBuilder{id: 115, commit: 64, name: "range-quantifier", ranges: [][]int{{1, 1}, {0, -1}, {0, 1}, {0, -1}, {1, 1}, {0, -1}, {0, 1}, {0, -1}, {1, 1}}}
|
||||
var b110 = sequenceBuilder{id: 110, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var b109 = charBuilder{}
|
||||
b110.items = []builder{&b109}
|
||||
var b107 = sequenceBuilder{id: 107, commit: 256, name: "range-from", ranges: [][]int{{1, 1}}}
|
||||
var b107 = sequenceBuilder{id: 107, commit: 64, name: "range-from", ranges: [][]int{{1, 1}}}
|
||||
b107.items = []builder{&b100}
|
||||
var b112 = sequenceBuilder{id: 112, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var b111 = charBuilder{}
|
||||
b112.items = []builder{&b111}
|
||||
var b108 = sequenceBuilder{id: 108, commit: 256, name: "range-to", ranges: [][]int{{1, 1}}}
|
||||
var b108 = sequenceBuilder{id: 108, commit: 64, name: "range-to", ranges: [][]int{{1, 1}}}
|
||||
b108.items = []builder{&b100}
|
||||
var b114 = sequenceBuilder{id: 114, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var b113 = charBuilder{}
|
||||
b114.items = []builder{&b113}
|
||||
b115.items = []builder{&b110, &b194, &b107, &b194, &b112, &b194, &b108, &b194, &b114}
|
||||
var b117 = sequenceBuilder{id: 117, commit: 264, name: "one-or-more", allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{122}}
|
||||
b115.items = []builder{&b110, &b186, &b107, &b186, &b112, &b186, &b108, &b186, &b114}
|
||||
var b117 = sequenceBuilder{id: 117, commit: 72, name: "one-or-more", allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var b116 = charBuilder{}
|
||||
b117.items = []builder{&b116}
|
||||
var b119 = sequenceBuilder{id: 119, commit: 264, name: "zero-or-more", allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{122}}
|
||||
var b119 = sequenceBuilder{id: 119, commit: 72, name: "zero-or-more", allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var b118 = charBuilder{}
|
||||
b119.items = []builder{&b118}
|
||||
var b121 = sequenceBuilder{id: 121, commit: 264, name: "zero-or-one", allChars: true, ranges: [][]int{{1, 1}, {1, 1}}, generalizations: []int{122}}
|
||||
var b121 = sequenceBuilder{id: 121, commit: 72, name: "zero-or-one", allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var b120 = charBuilder{}
|
||||
b121.items = []builder{&b120}
|
||||
b122.options = []builder{&b106, &b115, &b117, &b119, &b121}
|
||||
b124.items = []builder{&b123, &b122}
|
||||
var b125 = sequenceBuilder{id: 125, commit: 2, ranges: [][]int{{0, -1}, {1, 1}}}
|
||||
b125.items = []builder{&b194, &b124}
|
||||
b125.items = []builder{&b186, &b124}
|
||||
b126.items = []builder{&b124, &b125}
|
||||
var b132 = sequenceBuilder{id: 132, commit: 256, name: "choice", ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {0, -1}}, generalizations: []int{133}}
|
||||
var b127 = choiceBuilder{id: 127, commit: 258}
|
||||
var b132 = sequenceBuilder{id: 132, commit: 64, name: "choice", ranges: [][]int{{1, 1}, {0, -1}, {1, 1}, {0, -1}}}
|
||||
var b127 = choiceBuilder{id: 127, commit: 66}
|
||||
b127.options = []builder{&b89, &b92, &b97, &b126}
|
||||
var b130 = sequenceBuilder{id: 130, commit: 2, ranges: [][]int{{1, 1}, {0, -1}, {1, 1}}}
|
||||
var b129 = sequenceBuilder{id: 129, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var b128 = charBuilder{}
|
||||
b129.items = []builder{&b128}
|
||||
b130.items = []builder{&b129, &b194, &b127}
|
||||
b130.items = []builder{&b129, &b186, &b127}
|
||||
var b131 = sequenceBuilder{id: 131, commit: 2, ranges: [][]int{{0, -1}, {1, 1}}}
|
||||
b131.items = []builder{&b194, &b130}
|
||||
b132.items = []builder{&b127, &b194, &b130, &b131}
|
||||
b131.items = []builder{&b186, &b130}
|
||||
b132.items = []builder{&b127, &b186, &b130, &b131}
|
||||
b133.options = []builder{&b89, &b92, &b97, &b126, &b132}
|
||||
b177.items = []builder{&b174, &b194, &b176, &b194, &b133}
|
||||
var b183 = sequenceBuilder{id: 183, commit: 2, ranges: [][]int{{0, -1}, {1, 1}, {0, -1}}}
|
||||
var b181 = sequenceBuilder{id: 181, commit: 2, ranges: [][]int{{1, 1}, {0, -1}, {0, -1}, {1, 1}}}
|
||||
var b179 = sequenceBuilder{id: 179, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var b178 = charBuilder{}
|
||||
b179.items = []builder{&b178}
|
||||
var b180 = sequenceBuilder{id: 180, commit: 2, ranges: [][]int{{0, -1}, {1, 1}}}
|
||||
b180.items = []builder{&b194, &b179}
|
||||
b181.items = []builder{&b179, &b180, &b194, &b177}
|
||||
var b182 = sequenceBuilder{id: 182, commit: 2, ranges: [][]int{{0, -1}, {1, 1}}}
|
||||
b182.items = []builder{&b194, &b181}
|
||||
b183.items = []builder{&b194, &b181, &b182}
|
||||
b184.items = []builder{&b177, &b183}
|
||||
var b192 = sequenceBuilder{id: 192, commit: 2, ranges: [][]int{{0, -1}, {1, 1}, {0, -1}}}
|
||||
var b188 = sequenceBuilder{id: 188, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var b187 = charBuilder{}
|
||||
b188.items = []builder{&b187}
|
||||
var b191 = sequenceBuilder{id: 191, commit: 2, ranges: [][]int{{0, -1}, {1, 1}}}
|
||||
b191.items = []builder{&b194, &b188}
|
||||
b192.items = []builder{&b194, &b188, &b191}
|
||||
b195.items = []builder{&b190, &b194, &b184, &b192}
|
||||
b196.items = []builder{&b194, &b195, &b194}
|
||||
b169.items = []builder{&b166, &b186, &b168, &b186, &b133}
|
||||
var b175 = sequenceBuilder{id: 175, commit: 2, ranges: [][]int{{0, -1}, {1, 1}, {0, -1}}}
|
||||
var b173 = sequenceBuilder{id: 173, commit: 2, ranges: [][]int{{1, 1}, {0, -1}, {0, -1}, {1, 1}}}
|
||||
var b171 = sequenceBuilder{id: 171, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var b170 = charBuilder{}
|
||||
b171.items = []builder{&b170}
|
||||
var b172 = sequenceBuilder{id: 172, commit: 2, ranges: [][]int{{0, -1}, {1, 1}}}
|
||||
b172.items = []builder{&b186, &b171}
|
||||
b173.items = []builder{&b171, &b172, &b186, &b169}
|
||||
var b174 = sequenceBuilder{id: 174, commit: 2, ranges: [][]int{{0, -1}, {1, 1}}}
|
||||
b174.items = []builder{&b186, &b173}
|
||||
b175.items = []builder{&b186, &b173, &b174}
|
||||
b176.items = []builder{&b169, &b175}
|
||||
var b184 = sequenceBuilder{id: 184, commit: 2, ranges: [][]int{{0, -1}, {1, 1}, {0, -1}}}
|
||||
var b180 = sequenceBuilder{id: 180, commit: 10, allChars: true, ranges: [][]int{{1, 1}, {1, 1}}}
|
||||
var b179 = charBuilder{}
|
||||
b180.items = []builder{&b179}
|
||||
var b183 = sequenceBuilder{id: 183, commit: 2, ranges: [][]int{{0, -1}, {1, 1}}}
|
||||
b183.items = []builder{&b186, &b180}
|
||||
b184.items = []builder{&b186, &b180, &b183}
|
||||
b187.items = []builder{&b182, &b186, &b176, &b184}
|
||||
b188.items = []builder{&b186, &b187, &b186}
|
||||
|
||||
var keywords = []parser{}
|
||||
|
||||
return parseInput(r, &p196, &b196, keywords)
|
||||
return parseInput(r, &p188, &b188)
|
||||
}
|
||||
|
30
sequence.go
30
sequence.go
@ -52,20 +52,6 @@ func (p *sequenceParser) parse(c *context) {
|
||||
continue
|
||||
}
|
||||
|
||||
c.offset = from
|
||||
if c.fromResults(p) {
|
||||
if to > c.failOffset {
|
||||
c.failOffset = -1
|
||||
c.failingParser = nil
|
||||
}
|
||||
|
||||
if !p.allChars {
|
||||
c.results.unmarkPending(from, p.id)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if c.failingParser == nil &&
|
||||
p.commit&userDefined != 0 &&
|
||||
p.commit&Whitespace == 0 &&
|
||||
@ -94,22 +80,6 @@ func (p *sequenceParser) parse(c *context) {
|
||||
}
|
||||
}
|
||||
|
||||
if p.commit&NoKeyword != 0 && c.isKeyword(from, to) {
|
||||
if c.failingParser == nil &&
|
||||
p.commit&userDefined != 0 &&
|
||||
p.commit&Whitespace == 0 &&
|
||||
p.commit&FailPass == 0 {
|
||||
c.failingParser = p
|
||||
}
|
||||
|
||||
c.fail(from)
|
||||
if !p.allChars {
|
||||
c.results.unmarkPending(from, p.id)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
for _, g := range p.generalizations {
|
||||
if c.results.pending(from, g) {
|
||||
c.results.setMatch(from, g, to)
|
||||
|
@ -394,15 +394,6 @@ func (b *sequenceBuilder) generate(w io.Writer, done map[string]bool) error {
|
||||
fprintf("},")
|
||||
}
|
||||
|
||||
if len(b.generalizations) > 0 {
|
||||
fprintf("generalizations: []int{")
|
||||
for i := range b.generalizations {
|
||||
fprintf("%d,", b.generalizations[i])
|
||||
}
|
||||
|
||||
fprintf("},")
|
||||
}
|
||||
|
||||
fprintf("};")
|
||||
|
||||
if len(b.items) > 0 {
|
||||
|
130
syntax.go
130
syntax.go
@ -4,7 +4,8 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"code.squareroundforest.org/arpio/treerack/self"
|
||||
|
||||
"github.com/aryszka/treerack/self"
|
||||
)
|
||||
|
||||
// if min=0&&max=0, it means min=1,max=1
|
||||
@ -20,8 +21,9 @@ type Syntax struct {
|
||||
initialized bool
|
||||
initFailed bool
|
||||
explicitRoot bool
|
||||
keywords []definition
|
||||
root definition
|
||||
parser parser
|
||||
builder builder
|
||||
}
|
||||
|
||||
type GeneratorOptions struct {
|
||||
@ -55,33 +57,13 @@ var (
|
||||
ErrInitFailed = errors.New("init failed")
|
||||
ErrNoParsersDefined = errors.New("no parsers defined")
|
||||
ErrInvalidEscapeCharacter = errors.New("invalid escape character")
|
||||
ErrRootAlias = errors.New("root node cannot be an alias")
|
||||
ErrRootWhitespace = errors.New("root node cannot be a whitespace")
|
||||
ErrRootFailPass = errors.New("root node cannot pass failing definition")
|
||||
ErrMultipleRoots = errors.New("multiple roots")
|
||||
ErrInvalidSymbolName = errors.New("invalid symbol name")
|
||||
)
|
||||
|
||||
func (ct CommitType) String() string {
|
||||
switch ct {
|
||||
case None:
|
||||
return "none"
|
||||
case Alias:
|
||||
return "alias"
|
||||
case Whitespace:
|
||||
return "whitespace"
|
||||
case NoWhitespace:
|
||||
return "no-whitespace"
|
||||
case Keyword:
|
||||
return "keyword"
|
||||
case NoKeyword:
|
||||
return "no-keyword"
|
||||
case FailPass:
|
||||
return "fail-pass"
|
||||
case Root:
|
||||
return "root"
|
||||
default:
|
||||
return "unknown"
|
||||
}
|
||||
}
|
||||
|
||||
func duplicateDefinition(name string) error {
|
||||
return fmt.Errorf("duplicate definition: %s", name)
|
||||
}
|
||||
@ -118,36 +100,6 @@ func intsContain(is []int, i int) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
var incompatibleCommitTypes = map[CommitType][]CommitType{
|
||||
Alias: {Root},
|
||||
Whitespace: {Keyword, NoKeyword, FailPass, Root},
|
||||
Keyword: {NoKeyword, Root},
|
||||
FailPass: {Root},
|
||||
}
|
||||
|
||||
func (s *Syntax) checkCommitType(d definition) error {
|
||||
for ct, ict := range incompatibleCommitTypes {
|
||||
if d.commitType()&ct == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, cti := range ict {
|
||||
if d.commitType()&cti == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
return fmt.Errorf(
|
||||
"incompatible commit types in %s: %v and %v",
|
||||
d.nodeName(),
|
||||
ct,
|
||||
cti,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Syntax) applyRoot(d definition) error {
|
||||
explicitRoot := d.commitType()&Root != 0
|
||||
if explicitRoot && s.explicitRoot {
|
||||
@ -179,18 +131,10 @@ func (s *Syntax) register(d definition) error {
|
||||
s.registry = newRegistry()
|
||||
}
|
||||
|
||||
if err := s.checkCommitType(d); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := s.applyRoot(d); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if d.commitType()&Keyword != 0 {
|
||||
s.keywords = append(s.keywords, d)
|
||||
}
|
||||
|
||||
return s.registry.setDefinition(d)
|
||||
}
|
||||
|
||||
@ -308,12 +252,20 @@ func (s *Syntax) Init() error {
|
||||
return ErrNoParsersDefined
|
||||
}
|
||||
|
||||
if err := s.checkCommitType(s.root); err != nil {
|
||||
return err
|
||||
if s.root.commitType()&Alias != 0 {
|
||||
return ErrRootAlias
|
||||
}
|
||||
|
||||
if s.root.commitType()&Whitespace != 0 {
|
||||
return ErrRootWhitespace
|
||||
}
|
||||
|
||||
if s.root.commitType()&FailPass != 0 {
|
||||
return ErrRootFailPass
|
||||
}
|
||||
|
||||
defs := s.registry.definitions
|
||||
for i := range defs {
|
||||
for i := range s.registry.definitions {
|
||||
defs[i].preinit()
|
||||
}
|
||||
|
||||
@ -322,36 +274,19 @@ func (s *Syntax) Init() error {
|
||||
s.registry = newRegistry(defs...)
|
||||
}
|
||||
|
||||
for i := range s.keywords {
|
||||
if err := s.keywords[i].validate(s.registry); err != nil {
|
||||
s.initFailed = true
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := s.root.validate(s.registry); err != nil {
|
||||
s.initFailed = true
|
||||
return err
|
||||
}
|
||||
|
||||
for i := range s.keywords {
|
||||
s.keywords[i].init(s.registry)
|
||||
}
|
||||
|
||||
s.root.init(s.registry)
|
||||
s.parser = s.root.parser()
|
||||
s.builder = s.root.builder()
|
||||
|
||||
s.initialized = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Syntax) keywordParsers() []parser {
|
||||
var p []parser
|
||||
for _, kw := range s.keywords {
|
||||
p = append(p, kw.parser())
|
||||
}
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
func (s *Syntax) Generate(o GeneratorOptions, w io.Writer) error {
|
||||
if err := s.Init(); err != nil {
|
||||
return err
|
||||
@ -404,33 +339,18 @@ func (s *Syntax) Generate(o GeneratorOptions, w io.Writer) error {
|
||||
fprintln()
|
||||
|
||||
done := make(map[string]bool)
|
||||
for _, p := range s.keywordParsers() {
|
||||
if err := p.(generator).generate(w, done); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
fprintln()
|
||||
|
||||
if err := s.root.parser().(generator).generate(w, done); err != nil {
|
||||
if err := s.parser.(generator).generate(w, done); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
done = make(map[string]bool)
|
||||
if err := s.root.builder().(generator).generate(w, done); err != nil {
|
||||
if err := s.builder.(generator).generate(w, done); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fprintln()
|
||||
fprintln()
|
||||
fprint(`var keywords = []parser{`)
|
||||
for i := range s.keywords {
|
||||
fprintf(`&p%d, `, s.keywords[i].nodeID())
|
||||
}
|
||||
fprint(`}`)
|
||||
|
||||
fprintln()
|
||||
fprintln()
|
||||
fprintf(`return parseInput(r, &p%d, &b%d, keywords)`, s.root.parser().nodeID(), s.root.builder().nodeID())
|
||||
fprintf(`return parseInput(r, &p%d, &b%d)`, s.parser.nodeID(), s.builder.nodeID())
|
||||
fprintln()
|
||||
fprint(`}`)
|
||||
fprintln()
|
||||
@ -443,5 +363,5 @@ func (s *Syntax) Parse(r io.Reader) (*Node, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return parseInput(r, s.root.parser(), s.root.builder(), s.keywordParsers())
|
||||
return parseInput(r, s.parser, s.builder)
|
||||
}
|
||||
|
@ -59,11 +59,9 @@ expression:alias = terminal
|
||||
alias = "alias";
|
||||
ws = "ws";
|
||||
nows = "nows";
|
||||
kw = "kw";
|
||||
nokw = "nokw";
|
||||
failpass = "failpass";
|
||||
root = "root";
|
||||
flag:alias = alias | ws | nows | kw | nokw | failpass | root;
|
||||
flag:alias = alias | ws | nows | failpass | root;
|
||||
definition-name:alias:nows = symbol (":" flag)*;
|
||||
definition = definition-name "=" expression;
|
||||
|
||||
|
@ -137,14 +137,24 @@ func TestInit(t *testing.T) {
|
||||
|
||||
t.Run("root is an alias", func(t *testing.T) {
|
||||
s := &Syntax{}
|
||||
if err := s.AnyChar("a", Root|Alias); err == nil {
|
||||
if err := s.AnyChar("a", Root|Alias); err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := s.Init(); err == nil {
|
||||
t.Error("failed to fail")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("root is whitespace", func(t *testing.T) {
|
||||
s := &Syntax{}
|
||||
if err := s.AnyChar("a", Root|Whitespace); err == nil {
|
||||
if err := s.AnyChar("a", Root|Whitespace); err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := s.Init(); err == nil {
|
||||
t.Error("failed to fail")
|
||||
}
|
||||
})
|
||||
|
@ -14,8 +14,6 @@ const (
|
||||
Alias CommitType = 1 << iota
|
||||
Whitespace
|
||||
NoWhitespace
|
||||
Keyword
|
||||
NoKeyword
|
||||
FailPass
|
||||
Root
|
||||
|
||||
@ -82,8 +80,8 @@ func (pe *ParseError) Error() string {
|
||||
)
|
||||
}
|
||||
|
||||
func parseInput(r io.Reader, p parser, b builder, kw []parser) (*Node, error) {
|
||||
c := newContext(bufio.NewReader(r), kw)
|
||||
func parseInput(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
|
||||
|
Loading…
Reference in New Issue
Block a user