don't allocate nodes for chars

This commit is contained in:
Arpad Ryszka 2017-07-17 01:41:38 +02:00
parent 7c53a121de
commit 0b1a191856
7 changed files with 69 additions and 21 deletions

28
char.go
View File

@ -79,26 +79,26 @@ func (p *charParser) parse(t Trace, c *context) {
// t = t.Extend(p.name)
// t.Out1("parsing char", c.offset)
if p.commit&Documentation != 0 {
// t.Out1("fail, doc")
c.fail(c.offset)
return
}
// 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 _, 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)
// 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)
}
// for _, includedBy := range p.includedBy {
// includedBy.storeIncluded(c, n)
// }
c.success(n)
c.successChar()
return
} else {
// t.Out1("fail", string(tok))

View File

@ -125,6 +125,12 @@ func (c *context) success(n *Node) {
c.match = true
}
func (c *context) successChar() {
c.node = nil
c.offset++
c.match = true
}
func (c *context) fail(offset int) {
c.offset = offset
c.match = false

View File

@ -2863,7 +2863,11 @@ func TestMML(t *testing.T) {
}
func TestMMLFile(t *testing.T) {
const n = 18
if testing.Short() {
t.Skip()
}
const n = 180
s, err := testSyntax("mml.parser", 0)
if err != nil {

View File

@ -29,6 +29,14 @@ func (n *Node) nodeLength() int {
return len(n.Nodes)
}
func (n *Node) appendChar(to int) {
if n.tokenLength() == 0 {
n.From = to - 1
}
n.To = to
}
func (n *Node) append(p *Node) {
n.Nodes = append(n.Nodes, p)
if n.tokenLength() == 0 {

View File

@ -170,12 +170,16 @@ func (p *sequenceParser) parse(t Trace, c *context) {
continue
}
if c.node.tokenLength() > 0 {
// nil as char
if c.node == nil {
node.appendChar(c.offset)
currentCount++
} else if c.node.tokenLength() > 0 {
node.append(c.node)
currentCount++
}
if c.node.tokenLength() == 0 || ranges[0][1] >= 0 && currentCount == ranges[0][1] {
if c.node != nil && c.node.tokenLength() == 0 || ranges[0][1] >= 0 && currentCount == ranges[0][1] {
items = items[1:]
ranges = ranges[1:]
currentCount = 0

View File

@ -82,6 +82,27 @@ func (c *store) set(offset int, id int, n *Node) {
tc.nodes = append(tc.nodes, n)
}
/*
[][][]int
id, length, where to start in the underlying layer, which list in the layer
attibutes:
- sequence: length, the items in the layer below
- choice: the item below
features:
- there can be sequences or choices under choices
in every position:
- store the valid choices with the underlying parsed nodes
3D table: layer, choice, sequence
stored choice identified by: offset, layer, choice index
*/
func (c *store) inc() {
}

View File

@ -82,14 +82,19 @@ func (s *Syntax) AnyChar(name string, ct CommitType) error {
return s.Class(name, ct, true, nil, nil)
}
func (s *Syntax) Class(name string, ct CommitType, not bool, chars []rune, ranges [][]rune) error {
return s.register(newChar(name, ct, not, chars, ranges))
}
func childName(name string, childIndex int) string {
return fmt.Sprintf("%s:%d", name, childIndex)
}
func (s *Syntax) Class(name string, ct CommitType, not bool, chars []rune, ranges [][]rune) error {
cname := childName(name, 0)
if err := s.register(newChar(cname, Alias, not, chars, ranges)); err != nil {
return err
}
return s.Sequence(name, ct, SequenceItem{Name: cname})
}
func (s *Syntax) CharSequence(name string, ct CommitType, chars []rune) error {
var refs []string
for i, ci := range chars {