refactor definition phase
This commit is contained in:
parent
c96050347f
commit
f807c9d399
66
boot.go
66
boot.go
@ -29,71 +29,6 @@ func stringToCommitType(s string) CommitType {
|
||||
}
|
||||
}
|
||||
|
||||
func parseClass(class []rune) (not bool, chars []rune, ranges [][]rune, err error) {
|
||||
if class[0] == '^' {
|
||||
not = true
|
||||
class = class[1:]
|
||||
}
|
||||
|
||||
for {
|
||||
if len(class) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
var c0 rune
|
||||
c0, class = class[0], class[1:]
|
||||
|
||||
/*
|
||||
this doesn't happen:
|
||||
switch c0 {
|
||||
case '[', ']', '^', '-':
|
||||
err = errInvalidDefinition
|
||||
return
|
||||
}
|
||||
*/
|
||||
|
||||
if c0 == '\\' {
|
||||
/*
|
||||
this doesn't happen:
|
||||
if len(class) == 0 {
|
||||
err = errInvalidDefinition
|
||||
return
|
||||
}
|
||||
*/
|
||||
|
||||
c0, class = unescapeChar(class[0]), class[1:]
|
||||
}
|
||||
|
||||
if len(class) < 2 || class[0] != '-' {
|
||||
chars = append(chars, c0)
|
||||
continue
|
||||
}
|
||||
|
||||
var c1 rune
|
||||
c1, class = class[1], class[2:]
|
||||
|
||||
/*
|
||||
this doesn't happen:
|
||||
switch c1 {
|
||||
case '[', ']', '^', '-':
|
||||
err = errInvalidDefinition
|
||||
return
|
||||
}
|
||||
|
||||
if c1 == '\\' {
|
||||
if len(class) == 0 {
|
||||
err = errInvalidDefinition
|
||||
return
|
||||
}
|
||||
|
||||
c1, class = unescapeChar(class[0]), class[1:]
|
||||
}
|
||||
*/
|
||||
|
||||
ranges = append(ranges, []rune{c0, c1})
|
||||
}
|
||||
}
|
||||
|
||||
func defineBootAnything(s *Syntax, d []string) error {
|
||||
ct := stringToCommitType(d[2])
|
||||
return s.anyChar(d[1], ct)
|
||||
@ -233,6 +168,7 @@ func createBoot() (*Syntax, error) {
|
||||
func bootSyntax() (*Syntax, error) {
|
||||
/*
|
||||
never fails:
|
||||
|
||||
b, err := createBoot()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
4
char.go
4
char.go
@ -73,7 +73,7 @@ func (p *charParser) format(_ *registry, f formatFlags) string {
|
||||
return string(s)
|
||||
}
|
||||
|
||||
func matchChars(chars []rune, ranges [][]rune, not bool, char rune) bool {
|
||||
func matchChar(chars []rune, ranges [][]rune, not bool, char rune) bool {
|
||||
for _, ci := range chars {
|
||||
if ci == char {
|
||||
return !not
|
||||
@ -90,7 +90,7 @@ func matchChars(chars []rune, ranges [][]rune, not bool, char rune) bool {
|
||||
}
|
||||
|
||||
func (p *charParser) match(t rune) bool {
|
||||
return matchChars(p.chars, p.ranges, p.not, t)
|
||||
return matchChar(p.chars, p.ranges, p.not, t)
|
||||
}
|
||||
|
||||
func (p *charParser) parse(c *context) {
|
||||
|
10
define.go
10
define.go
@ -189,7 +189,7 @@ func defineExpression(s *Syntax, name string, ct CommitType, expression *Node) e
|
||||
return err
|
||||
}
|
||||
|
||||
func defineDefinition(s *Syntax, n *Node) error {
|
||||
func addDefinition(s *Syntax, n *Node) error {
|
||||
return defineExpression(
|
||||
s,
|
||||
n.Nodes[0].Text(),
|
||||
@ -198,11 +198,11 @@ func defineDefinition(s *Syntax, n *Node) error {
|
||||
)
|
||||
}
|
||||
|
||||
func define(s *Syntax, n *Node) error {
|
||||
n = dropComments(n)
|
||||
func define(s *Syntax, syntaxTree *Node) error {
|
||||
syntaxTree = dropComments(syntaxTree)
|
||||
|
||||
for _, ni := range n.Nodes {
|
||||
if err := defineDefinition(s, ni); err != nil {
|
||||
for _, n := range syntaxTree.Nodes {
|
||||
if err := addDefinition(s, n); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -351,3 +351,11 @@ func TestFailPass(t *testing.T) {
|
||||
},
|
||||
}})
|
||||
}
|
||||
|
||||
func TestFailPassRoot(t *testing.T) {
|
||||
const syntax = `foo:failpass = "foo"`
|
||||
_, err := openSyntaxString(syntax)
|
||||
if err == nil {
|
||||
t.Error("failed to fail")
|
||||
}
|
||||
}
|
||||
|
@ -2,15 +2,11 @@ package treerack
|
||||
|
||||
type registry struct {
|
||||
idSeed int
|
||||
ids map[string]int
|
||||
names map[int]string
|
||||
definitions map[string]definition
|
||||
}
|
||||
|
||||
func newRegistry(defs ...definition) *registry {
|
||||
r := ®istry{
|
||||
ids: make(map[string]int),
|
||||
names: make(map[int]string),
|
||||
definitions: make(map[string]definition),
|
||||
}
|
||||
|
||||
@ -34,8 +30,6 @@ func (r *registry) setDefinition(d definition) error {
|
||||
r.idSeed++
|
||||
id := r.idSeed
|
||||
d.setID(id)
|
||||
r.ids[d.nodeName()] = id
|
||||
r.names[id] = d.nodeName()
|
||||
|
||||
r.definitions[d.nodeName()] = d
|
||||
return nil
|
||||
|
74
syntax.go
74
syntax.go
@ -115,6 +115,7 @@ var (
|
||||
ErrInvalidSyntax = errors.New("invalid syntax")
|
||||
ErrRootAlias = errors.New("root node cannot be an alias")
|
||||
ErrRootWhitespace = errors.New("root node cannot be a whitespace")
|
||||
ErrRootFailPass = errors.New("root node cannot pass failing definition")
|
||||
ErrNotImplemented = errors.New("not implemented")
|
||||
ErrMultipleRoots = errors.New("multiple roots")
|
||||
ErrInvalidSymbolName = errors.New("invalid symbol name")
|
||||
@ -130,6 +131,71 @@ func parserNotFound(name string) error {
|
||||
|
||||
const symbolChars = "^\\\\ \\n\\t\\b\\f\\r\\v/.\\[\\]\\\"{}\\^+*?|():=;"
|
||||
|
||||
func parseClass(class []rune) (not bool, chars []rune, ranges [][]rune, err error) {
|
||||
if class[0] == '^' {
|
||||
not = true
|
||||
class = class[1:]
|
||||
}
|
||||
|
||||
for {
|
||||
if len(class) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
var c0 rune
|
||||
c0, class = class[0], class[1:]
|
||||
|
||||
/*
|
||||
this doesn't happen:
|
||||
switch c0 {
|
||||
case '[', ']', '^', '-':
|
||||
err = errInvalidDefinition
|
||||
return
|
||||
}
|
||||
*/
|
||||
|
||||
if c0 == '\\' {
|
||||
/*
|
||||
this doesn't happen:
|
||||
if len(class) == 0 {
|
||||
err = errInvalidDefinition
|
||||
return
|
||||
}
|
||||
*/
|
||||
|
||||
c0, class = unescapeChar(class[0]), class[1:]
|
||||
}
|
||||
|
||||
if len(class) < 2 || class[0] != '-' {
|
||||
chars = append(chars, c0)
|
||||
continue
|
||||
}
|
||||
|
||||
var c1 rune
|
||||
c1, class = class[1], class[2:]
|
||||
|
||||
/*
|
||||
this doesn't happen:
|
||||
switch c1 {
|
||||
case '[', ']', '^', '-':
|
||||
err = errInvalidDefinition
|
||||
return
|
||||
}
|
||||
|
||||
if c1 == '\\' {
|
||||
if len(class) == 0 {
|
||||
err = errInvalidDefinition
|
||||
return
|
||||
}
|
||||
|
||||
c1, class = unescapeChar(class[0]), class[1:]
|
||||
}
|
||||
*/
|
||||
|
||||
ranges = append(ranges, []rune{c0, c1})
|
||||
}
|
||||
}
|
||||
|
||||
func parseSymbolChars(c []rune) []rune {
|
||||
_, chars, _, _ := parseClass(c)
|
||||
return chars
|
||||
@ -140,7 +206,7 @@ var symbolCharRunes = parseSymbolChars([]rune(symbolChars))
|
||||
func isValidSymbol(n string) bool {
|
||||
runes := []rune(n)
|
||||
for _, r := range runes {
|
||||
if !matchChars(symbolCharRunes, nil, true, r) {
|
||||
if !matchChar(symbolCharRunes, nil, true, r) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
@ -275,8 +341,6 @@ func (s *Syntax) CharSequence(name string, ct CommitType, chars []rune) error {
|
||||
}
|
||||
|
||||
func (s *Syntax) sequence(name string, ct CommitType, items ...SequenceItem) error {
|
||||
citems := make([]SequenceItem, len(items))
|
||||
copy(citems, items)
|
||||
return s.register(newSequence(name, ct, items))
|
||||
}
|
||||
|
||||
@ -329,6 +393,10 @@ func (s *Syntax) Init() error {
|
||||
return ErrRootWhitespace
|
||||
}
|
||||
|
||||
if s.root.commitType()&FailPass != 0 {
|
||||
return ErrRootFailPass
|
||||
}
|
||||
|
||||
defs := s.registry.getDefinitions()
|
||||
for i := range defs {
|
||||
defs[i].preinit()
|
||||
|
Loading…
Reference in New Issue
Block a user