refactor init phase - core
This commit is contained in:
parent
c43dd97310
commit
52b2bcc751
25
char.go
25
char.go
@ -29,27 +29,24 @@ func (p *charParser) nodeID() int { return p.id }
|
|||||||
func (p *charParser) setID(id int) { p.id = id }
|
func (p *charParser) setID(id int) { p.id = id }
|
||||||
func (p *charParser) commitType() CommitType { return Alias }
|
func (p *charParser) commitType() CommitType { return Alias }
|
||||||
func (p *charParser) setCommitType(ct CommitType) {}
|
func (p *charParser) setCommitType(ct CommitType) {}
|
||||||
func (p *charParser) validate(*registry, *idSet) error { return nil }
|
func (p *charParser) validate(*registry) error { return nil }
|
||||||
func (p *charParser) normalize(*registry, *idSet) error { return nil }
|
func (p *charParser) init(*registry) {}
|
||||||
|
|
||||||
func (p *charParser) init(r *registry) error { return nil }
|
func (p *charParser) setIncludedBy(r *registry, includedBy int) {
|
||||||
|
if intsContain(p.includedBy, includedBy) {
|
||||||
func (p *charParser) setIncludedBy(r *registry, includedBy int, parsers *idSet) error {
|
return
|
||||||
p.includedBy = appendIfMissing(p.includedBy, includedBy)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *charParser) parser(r *registry, parsers *idSet) (parser, error) {
|
|
||||||
if parsers.has(p.id) {
|
|
||||||
panic(cannotIncludeParsers(p.name))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p.includedBy = append(p.includedBy, includedBy)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *charParser) parser(r *registry) parser {
|
||||||
if _, ok := r.parser(p.name); ok {
|
if _, ok := r.parser(p.name); ok {
|
||||||
return p, nil
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
r.setParser(p)
|
r.setParser(p)
|
||||||
return p, nil
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *charParser) builder() builder {
|
func (p *charParser) builder() builder {
|
||||||
|
69
choice.go
69
choice.go
@ -7,6 +7,8 @@ type choiceDefinition struct {
|
|||||||
elements []string
|
elements []string
|
||||||
includedBy []int
|
includedBy []int
|
||||||
cbuilder *choiceBuilder
|
cbuilder *choiceBuilder
|
||||||
|
validated bool
|
||||||
|
initialized bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type choiceParser struct {
|
type choiceParser struct {
|
||||||
@ -40,30 +42,34 @@ func (d *choiceDefinition) setID(id int) { d.id = id }
|
|||||||
func (d *choiceDefinition) commitType() CommitType { return d.commit }
|
func (d *choiceDefinition) commitType() CommitType { return d.commit }
|
||||||
func (d *choiceDefinition) setCommitType(ct CommitType) { d.commit = ct }
|
func (d *choiceDefinition) setCommitType(ct CommitType) { d.commit = ct }
|
||||||
|
|
||||||
func (d *choiceDefinition) validate(r *registry, path *idSet) error {
|
func (d *choiceDefinition) validate(r *registry) error {
|
||||||
|
if d.validated {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
d.validated = true
|
||||||
|
|
||||||
for i := range d.elements {
|
for i := range d.elements {
|
||||||
if _, ok := r.definitions[d.elements[i]]; !ok {
|
e, ok := r.definitions[d.elements[i]]
|
||||||
|
if !ok {
|
||||||
return parserNotFound(d.elements[i])
|
return parserNotFound(d.elements[i])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := e.validate(r); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *choiceDefinition) normalize(r *registry, path *idSet) error {
|
func (d *choiceDefinition) init(r *registry) {
|
||||||
if path.has(d.id) {
|
if d.initialized {
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
path.set(d.id)
|
d.initialized = true
|
||||||
for i := range d.elements {
|
|
||||||
r.definitions[d.elements[i]].normalize(r, path)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *choiceDefinition) init(r *registry) error {
|
|
||||||
if d.cbuilder == nil {
|
if d.cbuilder == nil {
|
||||||
d.cbuilder = &choiceBuilder{
|
d.cbuilder = &choiceBuilder{
|
||||||
name: d.name,
|
name: d.name,
|
||||||
@ -74,21 +80,19 @@ func (d *choiceDefinition) init(r *registry) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, e := range d.elements {
|
for _, e := range d.elements {
|
||||||
// TODO: handle undefined reference
|
def := r.definitions[e]
|
||||||
d.cbuilder.elements = append(d.cbuilder.elements, r.definitions[e].builder())
|
d.cbuilder.elements = append(d.cbuilder.elements, def.builder())
|
||||||
|
def.init(r)
|
||||||
|
def.setIncludedBy(r, d.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
parsers := &idSet{}
|
|
||||||
parsers.set(d.id)
|
|
||||||
return setItemsIncludedBy(r, d.elements, d.id, parsers)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *choiceDefinition) setIncludedBy(r *registry, includedBy int, parsers *idSet) error {
|
func (d *choiceDefinition) setIncludedBy(r *registry, includedBy int) {
|
||||||
if parsers.has(d.id) {
|
if intsContain(d.includedBy, includedBy) {
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
d.includedBy = appendIfMissing(d.includedBy, includedBy)
|
d.includedBy = append(d.includedBy, includedBy)
|
||||||
|
|
||||||
if d.cbuilder == nil {
|
if d.cbuilder == nil {
|
||||||
d.cbuilder = &choiceBuilder{
|
d.cbuilder = &choiceBuilder{
|
||||||
@ -101,18 +105,19 @@ func (d *choiceDefinition) setIncludedBy(r *registry, includedBy int, parsers *i
|
|||||||
|
|
||||||
d.cbuilder.includedBy.set(includedBy)
|
d.cbuilder.includedBy.set(includedBy)
|
||||||
|
|
||||||
parsers.set(d.id)
|
for _, e := range d.elements {
|
||||||
return setItemsIncludedBy(r, d.elements, includedBy, parsers)
|
r.definitions[e].setIncludedBy(r, includedBy)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
// - it may be possible to initialize the parsers non-recursively
|
// - it may be possible to initialize the parsers non-recursively
|
||||||
// - maybe the whole definition, parser and builder can be united
|
// - maybe the whole definition, parser and builder can be united
|
||||||
|
|
||||||
func (d *choiceDefinition) parser(r *registry, parsers *idSet) (parser, error) {
|
func (d *choiceDefinition) parser(r *registry) parser {
|
||||||
p, ok := r.parser(d.name)
|
p, ok := r.parser(d.name)
|
||||||
if ok {
|
if ok {
|
||||||
return p, nil
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
cp := &choiceParser{
|
cp := &choiceParser{
|
||||||
@ -125,8 +130,6 @@ func (d *choiceDefinition) parser(r *registry, parsers *idSet) (parser, error) {
|
|||||||
r.setParser(cp)
|
r.setParser(cp)
|
||||||
|
|
||||||
var elements []parser
|
var elements []parser
|
||||||
parsers.set(d.id)
|
|
||||||
defer parsers.unset(d.id)
|
|
||||||
for _, e := range d.elements {
|
for _, e := range d.elements {
|
||||||
element, ok := r.parser(e)
|
element, ok := r.parser(e)
|
||||||
if ok {
|
if ok {
|
||||||
@ -134,16 +137,12 @@ func (d *choiceDefinition) parser(r *registry, parsers *idSet) (parser, error) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
element, err := r.definitions[e].parser(r, parsers)
|
element = r.definitions[e].parser(r)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
elements = append(elements, element)
|
elements = append(elements, element)
|
||||||
}
|
}
|
||||||
|
|
||||||
cp.elements = elements
|
cp.elements = elements
|
||||||
return cp, nil
|
return cp
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *choiceDefinition) builder() builder {
|
func (d *choiceDefinition) builder() builder {
|
||||||
|
39
parse.go
39
parse.go
@ -9,11 +9,10 @@ type definition interface {
|
|||||||
commitType() CommitType
|
commitType() CommitType
|
||||||
setCommitType(CommitType)
|
setCommitType(CommitType)
|
||||||
setID(int)
|
setID(int)
|
||||||
validate(*registry, *idSet) error
|
validate(*registry) error
|
||||||
normalize(*registry, *idSet) error
|
init(*registry)
|
||||||
init(*registry) error
|
setIncludedBy(*registry, int)
|
||||||
setIncludedBy(*registry, int, *idSet) error
|
parser(*registry) parser
|
||||||
parser(*registry, *idSet) (parser, error)
|
|
||||||
builder() builder
|
builder() builder
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,36 +46,6 @@ func intsContain(is []int, i int) bool {
|
|||||||
return false
|
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
|
|
||||||
}
|
|
||||||
|
|
||||||
func parse(p parser, c *context) error {
|
func parse(p parser, c *context) error {
|
||||||
p.parse(c)
|
p.parse(c)
|
||||||
if c.readErr != nil {
|
if c.readErr != nil {
|
||||||
|
19
registry.go
19
registry.go
@ -8,13 +8,19 @@ type registry struct {
|
|||||||
parsers map[string]parser
|
parsers map[string]parser
|
||||||
}
|
}
|
||||||
|
|
||||||
func newRegistry() *registry {
|
func newRegistry(defs ...definition) *registry {
|
||||||
return ®istry{
|
r := ®istry{
|
||||||
ids: make(map[string]int),
|
ids: make(map[string]int),
|
||||||
names: make(map[int]string),
|
names: make(map[int]string),
|
||||||
definitions: make(map[string]definition),
|
definitions: make(map[string]definition),
|
||||||
parsers: make(map[string]parser),
|
parsers: make(map[string]parser),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, def := range defs {
|
||||||
|
r.setDefinition(def)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *registry) definition(name string) (definition, bool) {
|
func (r *registry) definition(name string) (definition, bool) {
|
||||||
@ -45,3 +51,12 @@ func (r *registry) setDefinition(d definition) error {
|
|||||||
func (r *registry) setParser(p parser) {
|
func (r *registry) setParser(p parser) {
|
||||||
r.parsers[p.nodeName()] = p
|
r.parsers[p.nodeName()] = p
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *registry) getDefinitions() []definition {
|
||||||
|
var defs []definition
|
||||||
|
for _, def := range r.definitions {
|
||||||
|
defs = append(defs, def)
|
||||||
|
}
|
||||||
|
|
||||||
|
return defs
|
||||||
|
}
|
||||||
|
95
sequence.go
95
sequence.go
@ -9,6 +9,8 @@ type sequenceDefinition struct {
|
|||||||
ranges [][]int
|
ranges [][]int
|
||||||
sbuilder *sequenceBuilder
|
sbuilder *sequenceBuilder
|
||||||
allChars bool
|
allChars bool
|
||||||
|
validated bool
|
||||||
|
initialized bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type sequenceParser struct {
|
type sequenceParser struct {
|
||||||
@ -46,36 +48,22 @@ func (d *sequenceDefinition) setID(id int) { d.id = id }
|
|||||||
func (d *sequenceDefinition) commitType() CommitType { return d.commit }
|
func (d *sequenceDefinition) commitType() CommitType { return d.commit }
|
||||||
func (d *sequenceDefinition) setCommitType(ct CommitType) { d.commit = ct }
|
func (d *sequenceDefinition) setCommitType(ct CommitType) { d.commit = ct }
|
||||||
|
|
||||||
func (d *sequenceDefinition) validate(r *registry, path *idSet) error {
|
func (d *sequenceDefinition) validate(r *registry) error {
|
||||||
|
if d.validated {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
d.validated = true
|
||||||
|
|
||||||
for i := range d.items {
|
for i := range d.items {
|
||||||
if _, ok := r.definition(d.items[i].Name); !ok {
|
ii, ok := r.definition(d.items[i].Name)
|
||||||
|
if !ok {
|
||||||
return parserNotFound(d.items[i].Name)
|
return parserNotFound(d.items[i].Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := ii.validate(r); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *sequenceDefinition) normalizeItems() {
|
|
||||||
for i := range d.items {
|
|
||||||
if d.items[i].Min == 0 && d.items[i].Max == 0 {
|
|
||||||
d.items[i].Min, d.items[i].Max = 1, 1
|
|
||||||
} else if d.items[i].Max == 0 {
|
|
||||||
d.items[i].Max = -1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *sequenceDefinition) normalize(r *registry, path *idSet) error {
|
|
||||||
if path.has(d.id) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// d.normalizeItems()
|
|
||||||
|
|
||||||
path.set(d.id)
|
|
||||||
for i := range d.items {
|
|
||||||
r.definitions[d.items[i].Name].normalize(r, path)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -85,7 +73,21 @@ func (d *sequenceDefinition) includeItems() bool {
|
|||||||
return len(d.items) == 1 && d.items[0].Min == 1 && d.items[0].Max == 1
|
return len(d.items) == 1 && d.items[0].Min == 1 && d.items[0].Max == 1
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *sequenceDefinition) init(r *registry) error {
|
func (d *sequenceDefinition) init(r *registry) {
|
||||||
|
if d.initialized {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
d.initialized = true
|
||||||
|
|
||||||
|
for i := range d.items {
|
||||||
|
if d.items[i].Min == 0 && d.items[i].Max == 0 {
|
||||||
|
d.items[i].Min, d.items[i].Max = 1, 1
|
||||||
|
} else if d.items[i].Max == 0 {
|
||||||
|
d.items[i].Max = -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if d.sbuilder == nil {
|
if d.sbuilder == nil {
|
||||||
d.sbuilder = &sequenceBuilder{
|
d.sbuilder = &sequenceBuilder{
|
||||||
name: d.name,
|
name: d.name,
|
||||||
@ -113,6 +115,8 @@ func (d *sequenceDefinition) init(r *registry) error {
|
|||||||
allChars = false
|
allChars = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def.init(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
d.sbuilder.ranges = d.ranges
|
d.sbuilder.ranges = d.ranges
|
||||||
@ -120,20 +124,18 @@ func (d *sequenceDefinition) init(r *registry) error {
|
|||||||
d.allChars = allChars
|
d.allChars = allChars
|
||||||
|
|
||||||
if !d.includeItems() {
|
if !d.includeItems() {
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
parsers := &idSet{}
|
r.definitions[d.items[0].Name].setIncludedBy(r, d.id)
|
||||||
parsers.set(d.id)
|
|
||||||
return setItemsIncludedBy(r, sequenceItemNames(d.items), d.id, parsers)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *sequenceDefinition) setIncludedBy(r *registry, includedBy int, parsers *idSet) error {
|
func (d *sequenceDefinition) setIncludedBy(r *registry, includedBy int) {
|
||||||
if parsers.has(d.id) {
|
if intsContain(d.includedBy, includedBy) {
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
d.includedBy = appendIfMissing(d.includedBy, includedBy)
|
d.includedBy = append(d.includedBy, includedBy)
|
||||||
|
|
||||||
if d.sbuilder == nil {
|
if d.sbuilder == nil {
|
||||||
d.sbuilder = &sequenceBuilder{
|
d.sbuilder = &sequenceBuilder{
|
||||||
@ -147,21 +149,16 @@ func (d *sequenceDefinition) setIncludedBy(r *registry, includedBy int, parsers
|
|||||||
d.sbuilder.includedBy.set(includedBy)
|
d.sbuilder.includedBy.set(includedBy)
|
||||||
|
|
||||||
if !d.includeItems() {
|
if !d.includeItems() {
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
parsers.set(d.id)
|
r.definitions[d.items[0].Name].setIncludedBy(r, includedBy)
|
||||||
return setItemsIncludedBy(r, sequenceItemNames(d.items), includedBy, parsers)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *sequenceDefinition) parser(r *registry, parsers *idSet) (parser, error) {
|
func (d *sequenceDefinition) parser(r *registry) parser {
|
||||||
if parsers.has(d.id) {
|
|
||||||
panic(cannotIncludeParsers(d.name))
|
|
||||||
}
|
|
||||||
|
|
||||||
p, ok := r.parser(d.name)
|
p, ok := r.parser(d.name)
|
||||||
if ok {
|
if ok {
|
||||||
return p, nil
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
sp := &sequenceParser{
|
sp := &sequenceParser{
|
||||||
@ -175,8 +172,6 @@ func (d *sequenceDefinition) parser(r *registry, parsers *idSet) (parser, error)
|
|||||||
r.setParser(sp)
|
r.setParser(sp)
|
||||||
|
|
||||||
var items []parser
|
var items []parser
|
||||||
parsers.set(d.id)
|
|
||||||
defer parsers.unset(d.id)
|
|
||||||
for _, item := range d.items {
|
for _, item := range d.items {
|
||||||
pi, ok := r.parser(item.Name)
|
pi, ok := r.parser(item.Name)
|
||||||
if ok {
|
if ok {
|
||||||
@ -184,17 +179,13 @@ func (d *sequenceDefinition) parser(r *registry, parsers *idSet) (parser, error)
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
pi, err := r.definitions[item.Name].parser(r, parsers)
|
pi = r.definitions[item.Name].parser(r)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
items = append(items, pi)
|
items = append(items, pi)
|
||||||
}
|
}
|
||||||
|
|
||||||
sp.items = items
|
sp.items = items
|
||||||
sp.ranges = d.ranges
|
sp.ranges = d.ranges
|
||||||
return sp, nil
|
return sp
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *sequenceDefinition) builder() builder {
|
func (d *sequenceDefinition) builder() builder {
|
||||||
|
29
syntax.go
29
syntax.go
@ -234,35 +234,22 @@ func (s *Syntax) Init() error {
|
|||||||
return ErrRootWhitespace
|
return ErrRootWhitespace
|
||||||
}
|
}
|
||||||
|
|
||||||
s.registry = initWhitespace(s.registry)
|
defs := s.registry.getDefinitions()
|
||||||
|
|
||||||
for _, def := range s.registry.definitions {
|
if hasWhitespace(defs) {
|
||||||
if def.commitType()&Root != 0 {
|
defs, s.root = applyWhitespace(defs)
|
||||||
s.root = def
|
s.registry = newRegistry(defs...)
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := s.root.validate(s.registry, &idSet{}); err != nil {
|
if err := s.root.validate(s.registry); err != nil {
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := s.root.normalize(s.registry, &idSet{}); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, p := range s.registry.definitions {
|
|
||||||
p.init(s.registry)
|
|
||||||
}
|
|
||||||
|
|
||||||
var err error
|
|
||||||
s.parser, err = s.root.parser(s.registry, &idSet{})
|
|
||||||
if err != nil {
|
|
||||||
s.initFailed = true
|
s.initFailed = true
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s.root.init(s.registry)
|
||||||
|
s.parser = s.root.parser(s.registry)
|
||||||
s.builder = s.root.builder()
|
s.builder = s.root.builder()
|
||||||
|
|
||||||
s.initialized = true
|
s.initialized = true
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -12,9 +12,9 @@ func brokenRegistryError(err error) error {
|
|||||||
return fmt.Errorf("broken registry: %v", err)
|
return fmt.Errorf("broken registry: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func splitWhitespaceDefs(all map[string]definition) ([]definition, []definition) {
|
func splitWhitespaceDefs(defs []definition) ([]definition, []definition) {
|
||||||
var whitespaceDefs, nonWhitespaceDefs []definition
|
var whitespaceDefs, nonWhitespaceDefs []definition
|
||||||
for _, def := range all {
|
for _, def := range defs {
|
||||||
if def.commitType()&Whitespace != 0 {
|
if def.commitType()&Whitespace != 0 {
|
||||||
def.setCommitType(def.commitType() | Alias)
|
def.setCommitType(def.commitType() | Alias)
|
||||||
whitespaceDefs = append(whitespaceDefs, def)
|
whitespaceDefs = append(whitespaceDefs, def)
|
||||||
@ -54,14 +54,10 @@ func mergeWhitespaceDefs(ws []definition) definition {
|
|||||||
return newChoice(whitespaceName, Alias, names)
|
return newChoice(whitespaceName, Alias, names)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: validate min and max
|
|
||||||
|
|
||||||
func patchName(s ...string) string {
|
func patchName(s ...string) string {
|
||||||
return strings.Join(s, ":")
|
return strings.Join(s, ":")
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: check what's more useful: update quantified char classes or not
|
|
||||||
|
|
||||||
func applyWhitespaceToSeq(s *sequenceDefinition) []definition {
|
func applyWhitespaceToSeq(s *sequenceDefinition) []definition {
|
||||||
var (
|
var (
|
||||||
defs []definition
|
defs []definition
|
||||||
@ -113,7 +109,7 @@ func applyWhitespaceToSeq(s *sequenceDefinition) []definition {
|
|||||||
return defs
|
return defs
|
||||||
}
|
}
|
||||||
|
|
||||||
func applyWhitespace(defs []definition) []definition {
|
func applyWhitespaceToDefs(defs []definition) []definition {
|
||||||
var defsWS []definition
|
var defsWS []definition
|
||||||
for _, def := range defs {
|
for _, def := range defs {
|
||||||
if def.commitType()&NoWhitespace != 0 {
|
if def.commitType()&NoWhitespace != 0 {
|
||||||
@ -133,7 +129,7 @@ func applyWhitespace(defs []definition) []definition {
|
|||||||
return defsWS
|
return defsWS
|
||||||
}
|
}
|
||||||
|
|
||||||
func applyWhitespaceRoot(root definition) (definition, definition) {
|
func applyWhitespaceToRoot(root definition) (definition, definition) {
|
||||||
original, name := root, root.nodeName()
|
original, name := root, root.nodeName()
|
||||||
wsName := patchName(name, "wsroot")
|
wsName := patchName(name, "wsroot")
|
||||||
|
|
||||||
@ -158,30 +154,34 @@ func applyWhitespaceRoot(root definition) (definition, definition) {
|
|||||||
return original, root
|
return original, root
|
||||||
}
|
}
|
||||||
|
|
||||||
func registerPatched(r *registry, defs ...definition) {
|
func hasWhitespace(defs []definition) bool {
|
||||||
for _, def := range defs {
|
for i := range defs {
|
||||||
if err := r.setDefinition(def); err != nil {
|
if defs[i].commitType()&Whitespace != 0 {
|
||||||
panic(brokenRegistryError(err))
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func initWhitespace(r *registry) *registry {
|
func applyWhitespace(defs []definition) ([]definition, definition) {
|
||||||
whitespaceDefs, defs := splitWhitespaceDefs(r.definitions)
|
whitespaceDefs, defs := splitWhitespaceDefs(defs)
|
||||||
if len(whitespaceDefs) == 0 {
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|
||||||
whitespace := mergeWhitespaceDefs(whitespaceDefs)
|
whitespace := mergeWhitespaceDefs(whitespaceDefs)
|
||||||
defs = applyWhitespace(defs)
|
|
||||||
|
defs = applyWhitespaceToDefs(defs)
|
||||||
|
|
||||||
root, defs := splitRoot(defs)
|
root, defs := splitRoot(defs)
|
||||||
originalRoot, root := applyWhitespaceRoot(root)
|
originalRoot, root := applyWhitespaceToRoot(root)
|
||||||
|
|
||||||
r = newRegistry()
|
defs = append(
|
||||||
registerPatched(r, whitespace)
|
append(
|
||||||
registerPatched(r, whitespaceDefs...)
|
defs,
|
||||||
registerPatched(r, defs...)
|
whitespaceDefs...,
|
||||||
registerPatched(r, originalRoot, root)
|
),
|
||||||
return r
|
whitespace,
|
||||||
|
originalRoot,
|
||||||
|
root,
|
||||||
|
)
|
||||||
|
|
||||||
|
return defs, root
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user