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
|
|
|
not bool
|
|
|
|
chars []rune
|
|
|
|
ranges [][]rune
|
2017-07-27 01:48:16 +02:00
|
|
|
includedBy []int
|
2017-06-25 17:51:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func newChar(
|
|
|
|
name string,
|
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,
|
|
|
|
not: not,
|
|
|
|
chars: chars,
|
|
|
|
ranges: ranges,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-06 20:32:59 +02:00
|
|
|
func (p *charParser) nodeName() string { return p.name }
|
2017-10-28 22:54:15 +02:00
|
|
|
func (p *charParser) setNodeName(n string) { p.name = n }
|
2017-08-06 20:32:59 +02:00
|
|
|
func (p *charParser) nodeID() int { return p.id }
|
|
|
|
func (p *charParser) setID(id int) { p.id = id }
|
|
|
|
func (p *charParser) commitType() CommitType { return Alias }
|
2017-10-28 22:54:15 +02:00
|
|
|
func (p *charParser) setCommitType(ct CommitType) {}
|
2017-08-06 20:43:52 +02:00
|
|
|
func (p *charParser) validate(*registry, *idSet) error { return nil }
|
2017-08-06 20:32:59 +02:00
|
|
|
func (p *charParser) normalize(*registry, *idSet) error { return nil }
|
2017-06-25 17:51:08 +02:00
|
|
|
|
2017-07-27 01:48:16 +02:00
|
|
|
func (p *charParser) init(r *registry) error { return nil }
|
|
|
|
|
|
|
|
func (p *charParser) setIncludedBy(r *registry, includedBy int, parsers *idSet) error {
|
|
|
|
p.includedBy = appendIfMissing(p.includedBy, includedBy)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2017-07-29 16:25:17 +02:00
|
|
|
func (p *charParser) builder() builder {
|
|
|
|
return p
|
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
|
|
|
|
}
|
|
|
|
|
2017-10-31 21:09:30 +01:00
|
|
|
func (p *charParser) parse(c *context) {
|
2017-07-17 04:23:29 +02:00
|
|
|
if tok, ok := c.token(); !ok || !p.match(tok) {
|
2017-06-25 17:51:08 +02:00
|
|
|
c.fail(c.offset)
|
|
|
|
return
|
|
|
|
}
|
2017-07-17 04:23:29 +02:00
|
|
|
|
|
|
|
c.success(c.offset + 1)
|
|
|
|
for _, includedBy := range p.includedBy {
|
2017-07-27 01:48:16 +02:00
|
|
|
c.store.setMatch(c.offset, includedBy, c.offset+1)
|
2017-07-17 04:23:29 +02:00
|
|
|
}
|
2017-06-25 17:51:08 +02:00
|
|
|
}
|
2017-07-29 16:25:17 +02:00
|
|
|
|
|
|
|
func (p *charParser) build(c *context) ([]*Node, bool) {
|
2017-07-30 03:08:45 +02:00
|
|
|
panic("called char build")
|
|
|
|
// // TODO: how to remove this check
|
|
|
|
// t, ok := c.token()
|
|
|
|
// if !ok {
|
|
|
|
// panic("damaged parser context")
|
|
|
|
// }
|
|
|
|
|
|
|
|
// if !p.match(t) {
|
|
|
|
// return nil, false
|
|
|
|
// }
|
|
|
|
|
|
|
|
// // always alias
|
|
|
|
// c.offset++
|
|
|
|
// return nil, true
|
2017-07-29 16:25:17 +02:00
|
|
|
}
|