remove node commit

This commit is contained in:
Arpad Ryszka 2017-07-17 04:23:29 +02:00
parent 0b1a191856
commit 2db706b1d1
11 changed files with 150 additions and 204 deletions

View File

@ -3,6 +3,7 @@ package treerack
import ( import (
"os" "os"
"testing" "testing"
"time"
) )
func TestBoot(t *testing.T) { func TestBoot(t *testing.T) {
@ -12,7 +13,7 @@ func TestBoot(t *testing.T) {
return return
} }
f, err := os.Open("syntax.parser") f, err := os.Open("mml.parser")
if err != nil { if err != nil {
t.Error(err) t.Error(err)
return return
@ -20,58 +21,65 @@ func TestBoot(t *testing.T) {
defer f.Close() defer f.Close()
n0, err := b.Parse(f) start := time.Now()
if err != nil { _, err = b.Parse(f)
t.Log("duration:", time.Now().Sub(start))
if err != ErrNotImplemented {
t.Error(err) t.Error(err)
return
} }
s0 := NewSyntax() // if err != nil {
if err := define(s0, n0); err != nil { // t.Error(err)
t.Error(err) // return
return // }
}
_, err = f.Seek(0, 0) // s0 := NewSyntax()
if err != nil { // if err := define(s0, n0); err != nil {
t.Error(err) // t.Error(err)
return // return
} // }
err = s0.Init() // _, err = f.Seek(0, 0)
if err != nil { // if err != nil {
t.Error(err) // t.Error(err)
return // return
} // }
n1, err := s0.Parse(f) // err = s0.Init()
if err != nil { // if err != nil {
t.Error(err) // t.Error(err)
return // return
} // }
checkNode(t, n1, n0) // n1, err := s0.Parse(f)
if t.Failed() { // if err != nil {
return // t.Error(err)
} // return
// }
s1 := NewSyntax() // checkNode(t, n1, n0)
if err := define(s1, n1); err != nil { // if t.Failed() {
t.Error(err) // return
return // }
}
_, err = f.Seek(0, 0) // s1 := NewSyntax()
if err != nil { // if err := define(s1, n1); err != nil {
t.Error(err) // t.Error(err)
return // return
} // }
n2, err := s1.Parse(f) // _, err = f.Seek(0, 0)
if err != nil { // if err != nil {
t.Error(err) // t.Error(err)
return // return
} // }
checkNode(t, n2, n1) // n2, err := s1.Parse(f)
// if err != nil {
// t.Error(err)
// return
// }
// checkNode(t, n2, n1)
} }

35
char.go
View File

@ -55,7 +55,7 @@ func (p *charParser) setIncludedBy(includedBy parser, parsers *idSet) {
p.includedBy = append(p.includedBy, includedBy) p.includedBy = append(p.includedBy, includedBy)
} }
func (p *charParser) storeIncluded(*context, *Node) { func (p *charParser) storeIncluded(*context, int, int) {
panic(cannotIncludeParsers(p.name)) panic(cannotIncludeParsers(p.name))
} }
@ -76,34 +76,13 @@ func (p *charParser) match(t rune) bool {
} }
func (p *charParser) parse(t Trace, c *context) { func (p *charParser) parse(t Trace, c *context) {
// t = t.Extend(p.name) if tok, ok := c.token(); !ok || !p.match(tok) {
// t.Out1("parsing char", c.offset)
// if p.commit&Documentation != 0 {
// // t.Out1("fail, doc")
// c.fail(c.offset)
// return
// }
// if _, ok := c.fromStore(p.id); ok {
// // t.Out1("found in store, match:", m)
// return
// }
if tok, ok := c.token(); ok && p.match(tok) {
// t.Out1("success", string(tok))
// n := newNode(p.name, p.id, c.offset, c.offset+1, p.commit)
// c.store.set(c.offset, p.id, n)
// for _, includedBy := range p.includedBy {
// includedBy.storeIncluded(c, n)
// }
c.successChar()
return
} else {
// t.Out1("fail", string(tok))
// c.store.set(c.offset, p.id, nil)
c.fail(c.offset) c.fail(c.offset)
return return
} }
c.success(c.offset + 1)
for _, includedBy := range p.includedBy {
includedBy.storeIncluded(c, c.offset, c.offset + 1)
}
} }

View File

@ -85,68 +85,60 @@ func (p *choiceParser) setIncludedBy(includedBy parser, parsers *idSet) {
p.includedBy = append(p.includedBy, includedBy) p.includedBy = append(p.includedBy, includedBy)
} }
func (p *choiceParser) storeIncluded(c *context, n *Node) { func (p *choiceParser) storeIncluded(c *context, from, to int) {
if !c.excluded(n.From, p.id) { if !c.excluded(from, p.id) {
return return
} }
nc := newNode(p.name, p.id, n.From, n.To, p.commit) c.store.set(from, p.id, true, to)
nc.append(n)
c.store.set(nc.From, p.id, nc)
for _, includedBy := range p.includedBy { for _, includedBy := range p.includedBy {
includedBy.storeIncluded(c, nc) includedBy.storeIncluded(c, from, to)
} }
} }
func (p *choiceParser) parse(t Trace, c *context) { func (p *choiceParser) parse(t Trace, c *context) {
// t = t.Extend(p.name)
// t.Out1("parsing choice", c.offset)
if p.commit&Documentation != 0 { if p.commit&Documentation != 0 {
// t.Out1("fail, doc")
c.fail(c.offset) c.fail(c.offset)
return return
} }
if _, ok := c.fromStore(p.id); ok { if _, ok := c.fromStore(p.id); ok {
// t.Out1("found in store, match:", m)
return return
} }
if c.excluded(c.offset, p.id) { if c.excluded(c.offset, p.id) {
// t.Out1("excluded")
c.fail(c.offset) c.fail(c.offset)
return return
} }
c.exclude(c.offset, p.id) c.exclude(c.offset, p.id)
initialOffset := c.offset from := c.offset
to := c.offset
node := newNode(p.name, p.id, c.offset, c.offset, p.commit)
var match bool var match bool
for { for {
elements := p.elements elementIndex := 0
var foundMatch bool var foundMatch bool
for len(elements) > 0 { for elementIndex < len(p.elements) {
elements[0].parse(t, c) p.elements[elementIndex].parse(t, c)
elements = elements[1:] elementIndex++
c.offset = node.From nextTo := c.offset
c.offset = from
if !c.match || match && c.node.tokenLength() <= node.tokenLength() { if !c.match || match && nextTo <= to {
continue continue
} }
match = true match = true
foundMatch = true foundMatch = true
node = newNode(p.name, p.id, c.offset, c.offset, p.commit) to = nextTo
node.append(c.node)
c.store.set(node.From, p.id, node) c.store.set(from, p.id, true, to)
for _, includedBy := range p.includedBy { for _, includedBy := range p.includedBy {
includedBy.storeIncluded(c, node) includedBy.storeIncluded(c, from, to)
} }
} }
@ -156,14 +148,12 @@ func (p *choiceParser) parse(t Trace, c *context) {
} }
if match { if match {
// t.Out1("choice, success") c.success(to)
c.success(node) c.include(from, p.id)
c.include(initialOffset, p.id)
return return
} }
// t.Out1("fail") c.store.set(from, p.id, false, 0)
c.store.set(node.From, p.id, nil) c.fail(from)
c.fail(node.From) c.include(from, p.id)
c.include(initialOffset, p.id)
} }

View File

@ -105,13 +105,13 @@ func (c *context) include(offset int, id int) {
} }
func (c *context) fromStore(id int) (bool, bool) { func (c *context) fromStore(id int) (bool, bool) {
n, m, ok := c.store.get(c.offset, id) to, m, ok := c.store.get(c.offset, id)
if !ok { if !ok {
return false, false return false, false
} }
if m { if m {
c.success(n) c.success(to)
} else { } else {
c.fail(c.offset) c.fail(c.offset)
} }
@ -119,15 +119,8 @@ func (c *context) fromStore(id int) (bool, bool) {
return m, true return m, true
} }
func (c *context) success(n *Node) { func (c *context) success(to int) {
c.node = n c.offset = to
c.offset = n.To
c.match = true
}
func (c *context) successChar() {
c.node = nil
c.offset++
c.match = true c.match = true
} }
@ -137,6 +130,8 @@ func (c *context) fail(offset int) {
} }
func (c *context) finalize() error { func (c *context) finalize() error {
return ErrNotImplemented
if c.node.To < c.readOffset { if c.node.To < c.readOffset {
return ErrUnexpectedCharacter return ErrUnexpectedCharacter
} }

View File

@ -1,12 +1,12 @@
// JSON (http://www.json.org) // JSON (http://www.json.org)
ws:alias = [ \b\f\n\r\t]; ws:ws = [ \b\f\n\r\t];
true = "true"; true = "true";
false = "false"; false = "false";
null = "null"; null = "null";
string = "\"" ([^\\"\b\f\n\r\t] | "\\" (["\\/bfnrt] | "u" [0-9a-f]{4}))* "\""; string:nows = "\"" ([^\\"\b\f\n\r\t] | "\\" (["\\/bfnrt] | "u" [0-9a-f]{4}))* "\"";
number = "-"? ("0" | [1-9][0-9]*) ("." [0-9]+)? ([eE] [+\-]? [0-9]+)?; number:nows = "-"? ("0" | [1-9][0-9]*) ("." [0-9]+)? ([eE] [+\-]? [0-9]+)?;
entry = string ws* ":" ws* value; entry = string ":" value;
object = "{" ws* (entry (ws* "," ws* entry)*)? ws* "}"; object = "{" (entry ("," entry)*)? "}";
array = "[" ws* (value (ws* "," ws* value)*)? ws* "]"; array = "[" (value ("," value)*)? "]";
value:alias = true | false | null | string | number | object | array; value:alias = true | false | null | string | number | object | array;
json = value; json:root = value;

View File

@ -15,8 +15,11 @@ coverage
custom tokens custom tokens
indentation indentation
streaming streaming
code generation go code generation go:
- find things that depend on the syntax input
- char matches can be generated into switches
code generation js code generation js
ws and nows flags
[problems] [problems]
can the root be an alias? check the commit mechanism can the root be an alias? check the commit mechanism

View File

@ -8,16 +8,23 @@ type definition interface {
setID(int) setID(int)
parser(*registry, *idSet) (parser, error) parser(*registry, *idSet) (parser, error)
commitType() CommitType commitType() CommitType
// builder() builder
} }
type parser interface { type parser interface {
nodeName() string nodeName() string
nodeID() int nodeID() int
setIncludedBy(parser, *idSet) setIncludedBy(parser, *idSet)
storeIncluded(*context, *Node) storeIncluded(*context, int, int)
parse(Trace, *context) parse(Trace, *context)
} }
type builder interface {
nodeName() string
nodeID() int
build(*context) *Node
}
func parserNotFound(name string) error { func parserNotFound(name string) error {
return fmt.Errorf("parser not found: %s", name) return fmt.Errorf("parser not found: %s", name)
} }
@ -26,16 +33,6 @@ func cannotIncludeParsers(name string) error {
return fmt.Errorf("parser: %s cannot include other parsers", name) return fmt.Errorf("parser: %s cannot include other parsers", name)
} }
func stringsContainDeprecated(ss []string, s string) bool {
for _, si := range ss {
if si == s {
return true
}
}
return false
}
func parse(t Trace, p parser, c *context) (*Node, error) { func parse(t Trace, p parser, c *context) (*Node, error) {
p.parse(t, c) p.parse(t, c)
if c.readErr != nil { if c.readErr != nil {

View File

@ -106,93 +106,67 @@ func (p *sequenceParser) setIncludedBy(includedBy parser, parsers *idSet) {
p.includedBy = append(p.includedBy, includedBy) p.includedBy = append(p.includedBy, includedBy)
} }
func (p *sequenceParser) storeIncluded(c *context, n *Node) { func (p *sequenceParser) storeIncluded(c *context, from, to int) {
if !c.excluded(n.From, p.id) { if !c.excluded(from, p.id) {
return return
} }
nc := newNode(p.name, p.id, n.From, n.To, p.commit) c.store.set(from, p.id, true, to)
nc.append(n)
c.store.set(nc.From, p.id, nc)
for _, includedBy := range p.includedBy { for _, includedBy := range p.includedBy {
includedBy.storeIncluded(c, nc) includedBy.storeIncluded(c, from, to)
} }
} }
func (p *sequenceParser) parse(t Trace, c *context) { func (p *sequenceParser) parse(t Trace, c *context) {
// t = t.Extend(p.name)
// t.Out1("parsing sequence", c.offset)
if p.commit&Documentation != 0 { if p.commit&Documentation != 0 {
// t.Out1("fail, doc")
c.fail(c.offset) c.fail(c.offset)
return return
} }
if c.excluded(c.offset, p.id) { if c.excluded(c.offset, p.id) {
// t.Out1("excluded")
c.fail(c.offset) c.fail(c.offset)
return return
} }
c.exclude(c.offset, p.id) c.exclude(c.offset, p.id)
initialOffset := c.offset
items := p.items itemIndex := 0
ranges := p.ranges
var currentCount int var currentCount int
node := newNode(p.name, p.id, c.offset, c.offset, p.commit) from := c.offset
to := c.offset
for len(items) > 0 { for itemIndex < len(p.items) {
var m bool p.items[itemIndex].parse(t, c)
// var ok bool if !c.match {
// m, ok = c.fromStore(items[0].nodeID()) if currentCount < p.ranges[itemIndex][0] {
// if ok { c.fail(from)
// // t.Out1("sequence item found in store, match:", m, items[0].nodeName(), c.offset) c.include(from, p.id)
// } else {
items[0].parse(t, c)
m = c.match
// }
if !m {
if currentCount < ranges[0][0] {
// t.Out1("fail, item failed")
// c.store.set(node.From, p.id, nil)
c.fail(node.From)
c.include(initialOffset, p.id)
return return
} }
items = items[1:] itemIndex++
ranges = ranges[1:]
currentCount = 0 currentCount = 0
continue continue
} }
// nil as char parsed := c.offset > to
if c.node == nil { if parsed {
node.appendChar(c.offset)
currentCount++
} else if c.node.tokenLength() > 0 {
node.append(c.node)
currentCount++ currentCount++
} }
if c.node != nil && c.node.tokenLength() == 0 || ranges[0][1] >= 0 && currentCount == ranges[0][1] { to = c.offset
items = items[1:]
ranges = ranges[1:] if !parsed || p.ranges[itemIndex][1] >= 0 && currentCount == p.ranges[itemIndex][1] {
itemIndex++
currentCount = 0 currentCount = 0
} }
} }
// t.Out1("success, items parsed")
// c.store.set(node.From, p.id, node)
for _, includedBy := range p.includedBy { for _, includedBy := range p.includedBy {
includedBy.storeIncluded(c, node) includedBy.storeIncluded(c, from, to)
} }
c.success(node) c.success(to)
c.include(initialOffset, p.id) c.include(from, p.id)
} }

View File

@ -3,41 +3,41 @@ package treerack
type storeEntry struct { type storeEntry struct {
match *idSet match *idSet
noMatch *idSet noMatch *idSet
nodes []*Node nodes []int
} }
type store struct { type store struct {
entries []*storeEntry entries []*storeEntry
} }
func (c *store) get(offset int, id int) (*Node, bool, bool) { func (c *store) get(offset int, id int) (int, bool, bool) {
if len(c.entries) <= offset { if len(c.entries) <= offset {
return nil, false, false return 0, false, false
} }
tc := c.entries[offset] tc := c.entries[offset]
if tc == nil { if tc == nil {
return nil, false, false return 0, false, false
} }
if tc.noMatch.has(id) { if tc.noMatch.has(id) {
return nil, false, true return 0, false, true
} }
if !tc.match.has(id) { if !tc.match.has(id) {
return nil, false, false return 0, false, false
} }
for _, n := range tc.nodes { for i := 0; i < len(tc.nodes); i += 2 {
if n.id == id { if tc.nodes[i] == id {
return n, true, true return tc.nodes[i + 1], true, true
} }
} }
return nil, false, false return 0, false, false
} }
func (c *store) set(offset int, id int, n *Node) { func (c *store) set(offset int, id int, match bool, to int) {
if len(c.entries) <= offset { if len(c.entries) <= offset {
if cap(c.entries) > offset { if cap(c.entries) > offset {
c.entries = c.entries[:offset+1] c.entries = c.entries[:offset+1]
@ -59,7 +59,7 @@ func (c *store) set(offset int, id int, n *Node) {
c.entries[offset] = tc c.entries[offset] = tc
} }
if n == nil { if !match {
if tc.match.has(id) { if tc.match.has(id) {
return return
} }
@ -69,17 +69,17 @@ func (c *store) set(offset int, id int, n *Node) {
} }
tc.match.set(id) tc.match.set(id)
for i, ni := range tc.nodes { for i := 0; i < len(tc.nodes); i += 2 {
if ni.id == id { if tc.nodes[i] == id {
if n.tokenLength() > ni.tokenLength() { if to > tc.nodes[i + 1] {
tc.nodes[i] = n tc.nodes[i + 1] = to
} }
return return
} }
} }
tc.nodes = append(tc.nodes, n) tc.nodes = append(tc.nodes, id, to)
} }
/* /*