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 {
|
func defineBootAnything(s *Syntax, d []string) error {
|
||||||
ct := stringToCommitType(d[2])
|
ct := stringToCommitType(d[2])
|
||||||
return s.anyChar(d[1], ct)
|
return s.anyChar(d[1], ct)
|
||||||
@ -233,6 +168,7 @@ func createBoot() (*Syntax, error) {
|
|||||||
func bootSyntax() (*Syntax, error) {
|
func bootSyntax() (*Syntax, error) {
|
||||||
/*
|
/*
|
||||||
never fails:
|
never fails:
|
||||||
|
|
||||||
b, err := createBoot()
|
b, err := createBoot()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
4
char.go
4
char.go
@ -73,7 +73,7 @@ func (p *charParser) format(_ *registry, f formatFlags) string {
|
|||||||
return string(s)
|
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 {
|
for _, ci := range chars {
|
||||||
if ci == char {
|
if ci == char {
|
||||||
return !not
|
return !not
|
||||||
@ -90,7 +90,7 @@ func matchChars(chars []rune, ranges [][]rune, not bool, char rune) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *charParser) match(t 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) {
|
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
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func defineDefinition(s *Syntax, n *Node) error {
|
func addDefinition(s *Syntax, n *Node) error {
|
||||||
return defineExpression(
|
return defineExpression(
|
||||||
s,
|
s,
|
||||||
n.Nodes[0].Text(),
|
n.Nodes[0].Text(),
|
||||||
@ -198,11 +198,11 @@ func defineDefinition(s *Syntax, n *Node) error {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func define(s *Syntax, n *Node) error {
|
func define(s *Syntax, syntaxTree *Node) error {
|
||||||
n = dropComments(n)
|
syntaxTree = dropComments(syntaxTree)
|
||||||
|
|
||||||
for _, ni := range n.Nodes {
|
for _, n := range syntaxTree.Nodes {
|
||||||
if err := defineDefinition(s, ni); err != nil {
|
if err := addDefinition(s, n); err != nil {
|
||||||
return err
|
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 {
|
type registry struct {
|
||||||
idSeed int
|
idSeed int
|
||||||
ids map[string]int
|
|
||||||
names map[int]string
|
|
||||||
definitions map[string]definition
|
definitions map[string]definition
|
||||||
}
|
}
|
||||||
|
|
||||||
func newRegistry(defs ...definition) *registry {
|
func newRegistry(defs ...definition) *registry {
|
||||||
r := ®istry{
|
r := ®istry{
|
||||||
ids: make(map[string]int),
|
|
||||||
names: make(map[int]string),
|
|
||||||
definitions: make(map[string]definition),
|
definitions: make(map[string]definition),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,8 +30,6 @@ func (r *registry) setDefinition(d definition) error {
|
|||||||
r.idSeed++
|
r.idSeed++
|
||||||
id := r.idSeed
|
id := r.idSeed
|
||||||
d.setID(id)
|
d.setID(id)
|
||||||
r.ids[d.nodeName()] = id
|
|
||||||
r.names[id] = d.nodeName()
|
|
||||||
|
|
||||||
r.definitions[d.nodeName()] = d
|
r.definitions[d.nodeName()] = d
|
||||||
return nil
|
return nil
|
||||||
|
74
syntax.go
74
syntax.go
@ -115,6 +115,7 @@ var (
|
|||||||
ErrInvalidSyntax = errors.New("invalid syntax")
|
ErrInvalidSyntax = errors.New("invalid syntax")
|
||||||
ErrRootAlias = errors.New("root node cannot be an alias")
|
ErrRootAlias = errors.New("root node cannot be an alias")
|
||||||
ErrRootWhitespace = errors.New("root node cannot be a whitespace")
|
ErrRootWhitespace = errors.New("root node cannot be a whitespace")
|
||||||
|
ErrRootFailPass = errors.New("root node cannot pass failing definition")
|
||||||
ErrNotImplemented = errors.New("not implemented")
|
ErrNotImplemented = errors.New("not implemented")
|
||||||
ErrMultipleRoots = errors.New("multiple roots")
|
ErrMultipleRoots = errors.New("multiple roots")
|
||||||
ErrInvalidSymbolName = errors.New("invalid symbol name")
|
ErrInvalidSymbolName = errors.New("invalid symbol name")
|
||||||
@ -130,6 +131,71 @@ func parserNotFound(name string) error {
|
|||||||
|
|
||||||
const symbolChars = "^\\\\ \\n\\t\\b\\f\\r\\v/.\\[\\]\\\"{}\\^+*?|():=;"
|
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 {
|
func parseSymbolChars(c []rune) []rune {
|
||||||
_, chars, _, _ := parseClass(c)
|
_, chars, _, _ := parseClass(c)
|
||||||
return chars
|
return chars
|
||||||
@ -140,7 +206,7 @@ var symbolCharRunes = parseSymbolChars([]rune(symbolChars))
|
|||||||
func isValidSymbol(n string) bool {
|
func isValidSymbol(n string) bool {
|
||||||
runes := []rune(n)
|
runes := []rune(n)
|
||||||
for _, r := range runes {
|
for _, r := range runes {
|
||||||
if !matchChars(symbolCharRunes, nil, true, r) {
|
if !matchChar(symbolCharRunes, nil, true, r) {
|
||||||
return false
|
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 {
|
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))
|
return s.register(newSequence(name, ct, items))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -329,6 +393,10 @@ func (s *Syntax) Init() error {
|
|||||||
return ErrRootWhitespace
|
return ErrRootWhitespace
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if s.root.commitType()&FailPass != 0 {
|
||||||
|
return ErrRootFailPass
|
||||||
|
}
|
||||||
|
|
||||||
defs := s.registry.getDefinitions()
|
defs := s.registry.getDefinitions()
|
||||||
for i := range defs {
|
for i := range defs {
|
||||||
defs[i].preinit()
|
defs[i].preinit()
|
||||||
|
Loading…
Reference in New Issue
Block a user