refactor definition phase

This commit is contained in:
Arpad Ryszka 2017-12-31 16:14:56 +01:00
parent c96050347f
commit f807c9d399
6 changed files with 87 additions and 81 deletions

66
boot.go
View File

@ -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

View File

@ -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) {

View File

@ -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
}
}

View File

@ -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")
}
}

View File

@ -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 := &registry{
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

View File

@ -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()