2017-07-15 21:49:08 +02:00
|
|
|
package treerack
|
2017-06-25 17:51:08 +02:00
|
|
|
|
2017-06-25 23:38:32 +02:00
|
|
|
import "fmt"
|
2017-06-25 17:51:08 +02:00
|
|
|
|
|
|
|
type definition interface {
|
|
|
|
nodeName() string
|
2017-07-15 21:49:08 +02:00
|
|
|
nodeID() int
|
2017-07-29 16:25:17 +02:00
|
|
|
commitType() CommitType
|
2017-07-15 21:49:08 +02:00
|
|
|
setID(int)
|
2017-08-06 20:32:59 +02:00
|
|
|
normalize(*registry, *idSet) error
|
2017-07-27 01:48:16 +02:00
|
|
|
init(*registry) error
|
|
|
|
setIncludedBy(*registry, int, *idSet) error
|
2017-07-15 22:12:01 +02:00
|
|
|
parser(*registry, *idSet) (parser, error)
|
2017-07-29 16:25:17 +02:00
|
|
|
builder() builder
|
2017-06-25 17:51:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
type parser interface {
|
|
|
|
nodeName() string
|
2017-07-15 21:49:08 +02:00
|
|
|
nodeID() int
|
2017-06-25 17:51:08 +02:00
|
|
|
parse(Trace, *context)
|
|
|
|
}
|
|
|
|
|
2017-07-17 04:23:29 +02:00
|
|
|
type builder interface {
|
|
|
|
nodeName() string
|
|
|
|
nodeID() int
|
2017-07-29 16:25:17 +02:00
|
|
|
build(*context) ([]*Node, bool)
|
2017-07-17 04:23:29 +02:00
|
|
|
}
|
|
|
|
|
2017-06-25 17:51:08 +02:00
|
|
|
func parserNotFound(name string) error {
|
|
|
|
return fmt.Errorf("parser not found: %s", name)
|
|
|
|
}
|
|
|
|
|
2017-06-25 23:38:32 +02:00
|
|
|
func cannotIncludeParsers(name string) error {
|
|
|
|
return fmt.Errorf("parser: %s cannot include other parsers", name)
|
|
|
|
}
|
|
|
|
|
2017-07-27 01:48:16 +02:00
|
|
|
func intsContain(is []int, i int) bool {
|
|
|
|
for _, ii := range is {
|
|
|
|
if ii == i {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
func appendIfMissing(is []int, i int) []int {
|
|
|
|
if intsContain(is, i) {
|
|
|
|
return is
|
|
|
|
}
|
|
|
|
|
|
|
|
return append(is, i)
|
|
|
|
}
|
|
|
|
|
|
|
|
func setItemsIncludedBy(r *registry, items []string, includedBy int, parsers *idSet) error {
|
|
|
|
for _, item := range items {
|
|
|
|
di, ok := r.definition(item)
|
|
|
|
if !ok {
|
|
|
|
return ErrNoParsersDefined
|
|
|
|
}
|
|
|
|
|
|
|
|
di.setIncludedBy(r, includedBy, parsers)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func sequenceItemNames(items []SequenceItem) []string {
|
|
|
|
names := make([]string, len(items))
|
|
|
|
for i := range items {
|
|
|
|
names[i] = items[i].Name
|
|
|
|
}
|
|
|
|
|
|
|
|
return names
|
|
|
|
}
|
|
|
|
|
2017-07-29 18:40:22 +02:00
|
|
|
func parse(t Trace, p parser, c *context) error {
|
2017-06-25 17:51:08 +02:00
|
|
|
p.parse(t, c)
|
|
|
|
if c.readErr != nil {
|
2017-07-29 18:40:22 +02:00
|
|
|
return c.readErr
|
2017-06-25 17:51:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if !c.match {
|
2017-07-29 18:40:22 +02:00
|
|
|
return ErrInvalidInput
|
2017-06-25 17:51:08 +02:00
|
|
|
}
|
|
|
|
|
2017-07-29 16:25:17 +02:00
|
|
|
if err := c.finalize(p); err != nil {
|
2017-07-29 18:40:22 +02:00
|
|
|
return err
|
2017-06-25 17:51:08 +02:00
|
|
|
}
|
|
|
|
|
2017-07-29 18:40:22 +02:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func build(b builder, c *context) *Node {
|
|
|
|
c.offset = 0
|
|
|
|
n, ok := b.build(c)
|
|
|
|
if !ok || len(n) != 1 {
|
|
|
|
panic("damaged parse result")
|
|
|
|
}
|
|
|
|
|
|
|
|
return n[0]
|
2017-06-25 17:51:08 +02:00
|
|
|
}
|