diff options
author | Ryo Nihei <nihei.dev@gmail.com> | 2021-06-28 01:25:54 +0900 |
---|---|---|
committer | Ryo Nihei <nihei.dev@gmail.com> | 2021-06-28 02:59:34 +0900 |
commit | f4bbd20fb97d6b91c9a53492fd945a4ac7ff4e5f (patch) | |
tree | d7c34a9521e130c6181e96d904fc02ef922e5991 /spec/parser.go | |
parent | Add syntax of fragment (diff) | |
download | cotia-f4bbd20fb97d6b91c9a53492fd945a4ac7ff4e5f.tar.gz cotia-f4bbd20fb97d6b91c9a53492fd945a4ac7ff4e5f.tar.xz |
Add ast action
Diffstat (limited to 'spec/parser.go')
-rw-r--r-- | spec/parser.go | 91 |
1 files changed, 73 insertions, 18 deletions
diff --git a/spec/parser.go b/spec/parser.go index a2c41f8..6f5e13f 100644 --- a/spec/parser.go +++ b/spec/parser.go @@ -32,7 +32,22 @@ type ElementNode struct { type ActionNode struct { Name string - Parameter string + Parameter *ParameterNode +} + +type ParameterNode struct { + ID string + Tree *TreeStructNode +} + +type TreeStructNode struct { + Name string + Children []*TreeChildNode +} + +type TreeChildNode struct { + Position int + Expansion bool } type FragmentNode struct { @@ -203,23 +218,7 @@ func (p *parser) parseAlternative() *AlternativeNode { elems = append(elems, elem) } - var act *ActionNode - if p.consume(tokenKindActionLeader) { - if !p.consume(tokenKindID) { - raiseSyntaxError(synErrNoActionName) - } - name := p.lastTok.text - - var param string - if p.consume(tokenKindID) { - param = p.lastTok.text - } - - act = &ActionNode{ - Name: name, - Parameter: param, - } - } + act := p.parseAction() return &AlternativeNode{ Elements: elems, @@ -241,6 +240,62 @@ func (p *parser) parseElement() *ElementNode { return nil } +func (p *parser) parseAction() *ActionNode { + if !p.consume(tokenKindActionLeader) { + return nil + } + + if !p.consume(tokenKindID) { + raiseSyntaxError(synErrNoActionName) + } + name := p.lastTok.text + + var param *ParameterNode + switch { + case p.consume(tokenKindID): + param = &ParameterNode{ + ID: p.lastTok.text, + } + case p.consume(tokenKindTreeNodeOpen): + if !p.consume(tokenKindID) { + raiseSyntaxError(synErrTreeInvalidFirstElem) + } + name := p.lastTok.text + + var children []*TreeChildNode + for { + if !p.consume(tokenKindPosition) { + break + } + + child := &TreeChildNode{ + Position: p.lastTok.num, + } + if p.consume(tokenKindExpantion) { + child.Expansion = true + } + + children = append(children, child) + } + + if !p.consume(tokenKindTreeNodeClose) { + raiseSyntaxError(synErrTreeUnclosed) + } + + param = &ParameterNode{ + Tree: &TreeStructNode{ + Name: name, + Children: children, + }, + } + } + + return &ActionNode{ + Name: name, + Parameter: param, + } +} + func (p *parser) consume(expected tokenKind) bool { var tok *token var err error |