zclwrite: initial attribute and basic expression parsing
This is not yet complete, since it fails to capture the newline, line comments, and variable references in expressions. However, it does capture the broad structure of an attribute, along with gathering up all of its _interior_ tokens.
This commit is contained in:
parent
15b38d8a48
commit
13c93e974f
@ -77,13 +77,17 @@ type Attribute struct {
|
||||
LeadCommentTokens *TokenSeq
|
||||
NameTokens *TokenSeq
|
||||
EqualsTokens *TokenSeq
|
||||
Value *Expression
|
||||
Expr *Expression
|
||||
LineCommentTokens *TokenSeq
|
||||
EOLTokens *TokenSeq
|
||||
}
|
||||
|
||||
func (a *Attribute) walkChildNodes(w internalWalkFunc) {
|
||||
w(a.Value)
|
||||
w(a.Expr)
|
||||
}
|
||||
|
||||
func (n *Attribute) Tokens() *TokenSeq {
|
||||
return n.AllTokens
|
||||
}
|
||||
|
||||
type Block struct {
|
||||
|
@ -146,12 +146,11 @@ func parseBodyItem(nativeItem zclsyntax.Node, from inputTokens) (inputTokens, No
|
||||
|
||||
var item Node
|
||||
|
||||
switch nativeItem.(type) {
|
||||
switch tItem := nativeItem.(type) {
|
||||
case *zclsyntax.Attribute:
|
||||
// TODO: actually deconstruct the attribute parts
|
||||
item = &Unstructured{
|
||||
AllTokens: within.Seq(),
|
||||
}
|
||||
item = parseAttribute(tItem, within)
|
||||
// TODO: Grab the newline and any line comment from "after" and
|
||||
// write them into the attribute object.
|
||||
case *zclsyntax.Block:
|
||||
// TODO: actually deconstruct the block parts
|
||||
item = &Unstructured{
|
||||
@ -165,6 +164,50 @@ func parseBodyItem(nativeItem zclsyntax.Node, from inputTokens) (inputTokens, No
|
||||
return before, item, after
|
||||
}
|
||||
|
||||
func parseAttribute(nativeAttr *zclsyntax.Attribute, from inputTokens) *Attribute {
|
||||
var allTokens TokenSeq
|
||||
attr := &Attribute{}
|
||||
|
||||
before, nameTokens, from := from.Partition(nativeAttr.NameRange)
|
||||
if before.Len() > 0 {
|
||||
allTokens = append(allTokens, before.Seq())
|
||||
}
|
||||
attr.NameTokens = nameTokens.Seq()
|
||||
allTokens = append(allTokens, attr.NameTokens)
|
||||
|
||||
before, equalsTokens, from := from.Partition(nativeAttr.EqualsRange)
|
||||
if before.Len() > 0 {
|
||||
allTokens = append(allTokens, before.Seq())
|
||||
}
|
||||
attr.EqualsTokens = equalsTokens.Seq()
|
||||
allTokens = append(allTokens, attr.EqualsTokens)
|
||||
|
||||
before, exprTokens, from := from.Partition(nativeAttr.Expr.Range())
|
||||
if before.Len() > 0 {
|
||||
allTokens = append(allTokens, before.Seq())
|
||||
}
|
||||
attr.Expr = parseExpression(nativeAttr.Expr, exprTokens)
|
||||
allTokens = append(allTokens, attr.Expr.AllTokens)
|
||||
|
||||
// Collect any stragglers, although we shouldn't generally have any since
|
||||
// the newline and any line comments don't get included in the attribute's
|
||||
// range.
|
||||
if from.Len() > 0 {
|
||||
allTokens = append(allTokens, from.Seq())
|
||||
}
|
||||
|
||||
attr.AllTokens = &allTokens
|
||||
|
||||
return attr
|
||||
}
|
||||
|
||||
func parseExpression(nativeExpr zclsyntax.Expression, from inputTokens) *Expression {
|
||||
// TODO: Populate VarRefs by analyzing the result of nativeExpr.Variables()
|
||||
return &Expression{
|
||||
AllTokens: from.Seq(),
|
||||
}
|
||||
}
|
||||
|
||||
// writerTokens takes a sequence of tokens as produced by the main zclsyntax
|
||||
// package and transforms it into an equivalent sequence of tokens using
|
||||
// this package's own token model.
|
||||
|
@ -27,43 +27,88 @@ func TestParse(t *testing.T) {
|
||||
"a = 1",
|
||||
&Body{
|
||||
Items: []Node{
|
||||
&Unstructured{
|
||||
AllTokens: &TokenSeq{Tokens{
|
||||
&Attribute{
|
||||
AllTokens: &TokenSeq{
|
||||
&TokenSeq{
|
||||
Tokens{
|
||||
{
|
||||
Type: zclsyntax.TokenIdent,
|
||||
Bytes: []byte(`a`),
|
||||
SpacesBefore: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
&TokenSeq{
|
||||
Tokens{
|
||||
{
|
||||
Type: zclsyntax.TokenEqual,
|
||||
Bytes: []byte(`=`),
|
||||
SpacesBefore: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
&TokenSeq{
|
||||
Tokens{
|
||||
{
|
||||
Type: zclsyntax.TokenNumberLit,
|
||||
Bytes: []byte(`1`),
|
||||
SpacesBefore: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
NameTokens: &TokenSeq{Tokens{
|
||||
{
|
||||
Type: zclsyntax.TokenIdent,
|
||||
Bytes: []byte(`a`),
|
||||
SpacesBefore: 0,
|
||||
},
|
||||
}},
|
||||
EqualsTokens: &TokenSeq{Tokens{
|
||||
{
|
||||
Type: zclsyntax.TokenEqual,
|
||||
Bytes: []byte(`=`),
|
||||
SpacesBefore: 1,
|
||||
},
|
||||
{
|
||||
Type: zclsyntax.TokenNumberLit,
|
||||
Bytes: []byte(`1`),
|
||||
SpacesBefore: 1,
|
||||
},
|
||||
}},
|
||||
Expr: &Expression{
|
||||
AllTokens: &TokenSeq{Tokens{
|
||||
{
|
||||
Type: zclsyntax.TokenNumberLit,
|
||||
Bytes: []byte(`1`),
|
||||
SpacesBefore: 1,
|
||||
},
|
||||
}},
|
||||
},
|
||||
},
|
||||
},
|
||||
AllTokens: &TokenSeq{
|
||||
&TokenSeq{
|
||||
Tokens{
|
||||
{
|
||||
Type: zclsyntax.TokenIdent,
|
||||
Bytes: []byte(`a`),
|
||||
SpacesBefore: 0,
|
||||
&TokenSeq{
|
||||
Tokens{
|
||||
{
|
||||
Type: zclsyntax.TokenIdent,
|
||||
Bytes: []byte(`a`),
|
||||
SpacesBefore: 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
Type: zclsyntax.TokenEqual,
|
||||
Bytes: []byte(`=`),
|
||||
SpacesBefore: 1,
|
||||
},
|
||||
&TokenSeq{
|
||||
Tokens{
|
||||
{
|
||||
Type: zclsyntax.TokenEqual,
|
||||
Bytes: []byte(`=`),
|
||||
SpacesBefore: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
Type: zclsyntax.TokenNumberLit,
|
||||
Bytes: []byte(`1`),
|
||||
SpacesBefore: 1,
|
||||
},
|
||||
&TokenSeq{
|
||||
Tokens{
|
||||
{
|
||||
Type: zclsyntax.TokenNumberLit,
|
||||
Bytes: []byte(`1`),
|
||||
SpacesBefore: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user