treerack/char.go

108 lines
2.3 KiB
Go
Raw Normal View History

2017-07-15 21:49:08 +02:00
package treerack
2017-06-25 17:51:08 +02:00
2017-11-26 01:49:22 +01:00
const (
charClassEscape = '\\'
charClassBanned = "\\[]^-\b\f\n\r\t\v"
)
2017-06-25 17:51:08 +02:00
type charParser struct {
2017-11-02 22:19:03 +01:00
name string
id int
not bool
chars []rune
ranges [][]rune
generalizations []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-11-01 02:43:46 +01:00
func (p *charParser) nodeName() string { return p.name }
2017-11-05 03:28:36 +01:00
func (p *charParser) setName(n string) { p.name = n }
2017-11-01 02:43:46 +01: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 }
func (p *charParser) setCommitType(ct CommitType) {}
2017-11-04 22:49:42 +01:00
func (p *charParser) preinit() {}
2017-11-01 02:43:46 +01:00
func (p *charParser) validate(*registry) error { return nil }
func (p *charParser) init(*registry) {}
2017-11-05 03:28:36 +01:00
func (p *charParser) addGeneralization(int) {}
func (p *charParser) parser() parser { return p }
func (p *charParser) builder() builder { return p }
2017-06-25 17:51:08 +02:00
2017-11-26 01:49:22 +01:00
func (p *charParser) isSingleChar() bool {
return !p.not && len(p.chars) == 1 && len(p.ranges) == 0
}
func (p *charParser) format(_ *registry, f formatFlags) string {
if p.not && len(p.chars) == 0 && len(p.ranges) == 0 {
return "."
}
esc := func(c ...rune) []rune {
return escape(charClassEscape, []rune(charClassBanned), c)
}
var s []rune
s = append(s, '[')
if p.not {
s = append(s, '^')
}
s = append(s, esc(p.chars...)...)
for i := range p.ranges {
s = append(s, esc(p.ranges[i][0])...)
s = append(s, '-')
s = append(s, esc(p.ranges[i][1])...)
}
s = append(s, ']')
return string(s)
}
2017-10-31 21:53:09 +01:00
func matchChars(chars []rune, ranges [][]rune, not bool, char rune) bool {
for _, ci := range chars {
if ci == char {
return !not
2017-06-25 17:51:08 +02:00
}
}
2017-10-31 21:53:09 +01:00
for _, ri := range ranges {
if char >= ri[0] && char <= ri[1] {
return !not
2017-06-25 17:51:08 +02:00
}
}
2017-10-31 21:53:09 +01:00
return not
}
func (p *charParser) match(t rune) bool {
return matchChars(p.chars, p.ranges, p.not, t)
2017-06-25 17:51:08 +02:00
}
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
2017-11-01 00:19:29 +01:00
c.success(c.offset + 1)
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-11-05 03:28:36 +01:00
return nil, false
2017-07-29 16:25:17 +02:00
}