treerack/char.go

110 lines
2.0 KiB
Go
Raw Normal View History

2017-07-15 21:49:08 +02:00
package treerack
2017-06-25 17:51:08 +02:00
type charParser struct {
name string
2017-07-15 21:49:08 +02:00
id int
2017-06-25 17:51:08 +02:00
commit CommitType
not bool
chars []rune
ranges [][]rune
includedBy []parser
}
func newChar(
name string,
ct CommitType,
2017-06-25 23:38:32 +02:00
not bool,
2017-06-25 17:51:08 +02:00
chars []rune,
ranges [][]rune,
) *charParser {
return &charParser{
name: name,
commit: ct,
not: not,
chars: chars,
ranges: ranges,
}
}
func (p *charParser) nodeName() string { return p.name }
2017-07-15 21:49:08 +02:00
func (p *charParser) nodeID() int { return p.id }
2017-07-15 23:00:43 +02:00
func (p *charParser) setID(id int) { p.id = id }
2017-06-25 17:51:08 +02:00
2017-07-15 22:12:01 +02:00
func (p *charParser) parser(r *registry, parsers *idSet) (parser, error) {
if parsers.has(p.id) {
2017-06-25 23:38:32 +02:00
panic(cannotIncludeParsers(p.name))
}
if _, ok := r.parser(p.name); ok {
return p, nil
2017-06-25 17:51:08 +02:00
}
r.setParser(p)
return p, nil
}
func (p *charParser) commitType() CommitType {
return p.commit
}
2017-07-15 22:12:01 +02:00
func (p *charParser) setIncludedBy(includedBy parser, parsers *idSet) {
if parsers.has(p.id) {
2017-06-25 23:38:32 +02:00
panic(cannotIncludeParsers(p.name))
2017-06-25 17:51:08 +02:00
}
2017-06-26 00:04:16 +02:00
p.includedBy = append(p.includedBy, includedBy)
2017-06-25 17:51:08 +02:00
}
2017-06-26 02:20:23 +02:00
func (p *charParser) storeIncluded(*context, *Node) {
2017-06-25 23:38:32 +02:00
panic(cannotIncludeParsers(p.name))
2017-06-25 17:51:08 +02:00
}
func (p *charParser) match(t rune) bool {
for _, ci := range p.chars {
if ci == t {
return !p.not
}
}
for _, ri := range p.ranges {
if t >= ri[0] && t <= ri[1] {
return !p.not
}
}
return p.not
}
func (p *charParser) parse(t Trace, c *context) {
2017-06-26 00:20:54 +02:00
// t = t.Extend(p.name)
// t.Out1("parsing char", c.offset)
2017-06-25 17:51:08 +02:00
if p.commit&Documentation != 0 {
2017-06-26 00:20:54 +02:00
// t.Out1("fail, doc")
2017-06-25 17:51:08 +02:00
c.fail(c.offset)
return
}
2017-07-15 23:00:43 +02:00
if _, ok := c.fromStore(p.id); ok {
2017-06-26 02:20:23 +02:00
// t.Out1("found in store, match:", m)
2017-06-25 17:51:08 +02:00
return
}
if tok, ok := c.token(); ok && p.match(tok) {
2017-06-26 00:20:54 +02:00
// t.Out1("success", string(tok))
2017-07-15 21:49:08 +02:00
n := newNode(p.name, p.id, c.offset, c.offset+1, p.commit)
2017-07-15 23:00:43 +02:00
c.store.set(c.offset, p.id, n)
2017-06-26 00:04:16 +02:00
for _, includedBy := range p.includedBy {
2017-06-26 02:20:23 +02:00
includedBy.storeIncluded(c, n)
2017-06-25 17:51:08 +02:00
}
c.success(n)
return
} else {
2017-06-26 00:20:54 +02:00
// t.Out1("fail", string(tok))
2017-07-15 23:00:43 +02:00
c.store.set(c.offset, p.id, nil)
2017-06-25 17:51:08 +02:00
c.fail(c.offset)
return
}
}