config/lang: have position in AST
This commit is contained in:
parent
d3b1010444
commit
662760da11
|
@ -1,9 +1,25 @@
|
|||
package ast
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Node is the interface that all AST nodes must implement.
|
||||
type Node interface {
|
||||
// Accept is called to dispatch to the visitors.
|
||||
Accept(Visitor)
|
||||
|
||||
// Pos returns the position of this node in some source.
|
||||
Pos() Pos
|
||||
}
|
||||
|
||||
// Pos is the starting position of an AST node
|
||||
type Pos struct {
|
||||
Column, Line int // Column/Line number, starting at 1
|
||||
}
|
||||
|
||||
func (p *Pos) String() string {
|
||||
return fmt.Sprintf("%d:%d", p.Line, p.Column)
|
||||
}
|
||||
|
||||
// Visitors are just implementations of this function.
|
||||
|
|
|
@ -4,6 +4,7 @@ package ast
|
|||
type Call struct {
|
||||
Func string
|
||||
Args []Node
|
||||
Posx Pos
|
||||
}
|
||||
|
||||
func (n *Call) Accept(v Visitor) {
|
||||
|
@ -13,3 +14,7 @@ func (n *Call) Accept(v Visitor) {
|
|||
|
||||
v(n)
|
||||
}
|
||||
|
||||
func (n *Call) Pos() Pos {
|
||||
return n.Posx
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
// concatenated. The result of all expressions must be a string.
|
||||
type Concat struct {
|
||||
Exprs []Node
|
||||
Posx Pos
|
||||
}
|
||||
|
||||
func (n *Concat) Accept(v Visitor) {
|
||||
|
@ -18,6 +19,10 @@ func (n *Concat) Accept(v Visitor) {
|
|||
v(n)
|
||||
}
|
||||
|
||||
func (n *Concat) Pos() Pos {
|
||||
return n.Posx
|
||||
}
|
||||
|
||||
func (n *Concat) GoString() string {
|
||||
return fmt.Sprintf("*%#v", *n)
|
||||
}
|
||||
|
|
|
@ -9,12 +9,17 @@ import (
|
|||
type LiteralNode struct {
|
||||
Value interface{}
|
||||
Type Type
|
||||
Posx Pos
|
||||
}
|
||||
|
||||
func (n *LiteralNode) Accept(v Visitor) {
|
||||
v(n)
|
||||
}
|
||||
|
||||
func (n *LiteralNode) Pos() Pos {
|
||||
return n.Posx
|
||||
}
|
||||
|
||||
func (n *LiteralNode) GoString() string {
|
||||
return fmt.Sprintf("*%#v", *n)
|
||||
}
|
||||
|
|
|
@ -7,12 +7,17 @@ import (
|
|||
// VariableAccess represents a variable access.
|
||||
type VariableAccess struct {
|
||||
Name string
|
||||
Posx Pos
|
||||
}
|
||||
|
||||
func (n *VariableAccess) Accept(v Visitor) {
|
||||
v(n)
|
||||
}
|
||||
|
||||
func (n *VariableAccess) Pos() Pos {
|
||||
return n.Posx
|
||||
}
|
||||
|
||||
func (n *VariableAccess) GoString() string {
|
||||
return fmt.Sprintf("*%#v", *n)
|
||||
}
|
||||
|
|
|
@ -15,12 +15,15 @@ import (
|
|||
node ast.Node
|
||||
nodeList []ast.Node
|
||||
str string
|
||||
token *parserToken
|
||||
}
|
||||
|
||||
%token <str> STRING IDENTIFIER PROGRAM_BRACKET_LEFT PROGRAM_BRACKET_RIGHT
|
||||
%token <str> PROGRAM_BRACKET_LEFT PROGRAM_BRACKET_RIGHT
|
||||
%token <str> PROGRAM_STRING_START PROGRAM_STRING_END
|
||||
%token <str> PAREN_LEFT PAREN_RIGHT COMMA
|
||||
|
||||
%token <token> IDENTIFIER STRING
|
||||
|
||||
%type <node> expr interpolation literal literalModeTop literalModeValue
|
||||
%type <nodeList> args
|
||||
|
||||
|
@ -48,6 +51,7 @@ literalModeTop:
|
|||
|
||||
$$ = &ast.Concat{
|
||||
Exprs: result,
|
||||
Posx: result[0].Pos(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -74,11 +78,11 @@ expr:
|
|||
}
|
||||
| IDENTIFIER
|
||||
{
|
||||
$$ = &ast.VariableAccess{Name: $1}
|
||||
$$ = &ast.VariableAccess{Name: $1.Value.(string), Posx: $1.Pos}
|
||||
}
|
||||
| IDENTIFIER PAREN_LEFT args PAREN_RIGHT
|
||||
{
|
||||
$$ = &ast.Call{Func: $1, Args: $3}
|
||||
$$ = &ast.Call{Func: $1.Value.(string), Args: $3, Posx: $1.Pos}
|
||||
}
|
||||
|
||||
args:
|
||||
|
@ -97,7 +101,11 @@ args:
|
|||
literal:
|
||||
STRING
|
||||
{
|
||||
$$ = &ast.LiteralNode{Value: $1, Type: ast.TypeString}
|
||||
$$ = &ast.LiteralNode{
|
||||
Value: $1.Value.(string),
|
||||
Type: ast.TypeString,
|
||||
Posx: $1.Pos,
|
||||
}
|
||||
}
|
||||
|
||||
%%
|
||||
|
|
|
@ -5,6 +5,8 @@ import (
|
|||
"fmt"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/hashicorp/terraform/config/lang/ast"
|
||||
)
|
||||
|
||||
//go:generate go tool yacc -p parser lang.y
|
||||
|
@ -22,6 +24,17 @@ type parserLex struct {
|
|||
interpolationDepth int
|
||||
pos int
|
||||
width int
|
||||
col, line int
|
||||
lastLine int
|
||||
astPos *ast.Pos
|
||||
}
|
||||
|
||||
// parserToken is the token yielded to the parser. The value can be
|
||||
// determined within the parser type based on the enum value returned
|
||||
// from Lex.
|
||||
type parserToken struct {
|
||||
Value interface{}
|
||||
Pos ast.Pos
|
||||
}
|
||||
|
||||
// parserMode keeps track of what mode we're in for the parser. We have
|
||||
|
@ -43,6 +56,17 @@ func (x *parserLex) Lex(yylval *parserSymType) int {
|
|||
x.mode = parserModeLiteral
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if yylval.token != nil && yylval.token.Pos.Column == 0 {
|
||||
yylval.token.Pos = *x.astPos
|
||||
}
|
||||
}()
|
||||
|
||||
x.astPos = nil
|
||||
return x.lex(yylval)
|
||||
}
|
||||
|
||||
func (x *parserLex) lex(yylval *parserSymType) int {
|
||||
switch x.mode {
|
||||
case parserModeLiteral:
|
||||
return x.lexModeLiteral(yylval)
|
||||
|
@ -81,8 +105,8 @@ func (x *parserLex) lexModeLiteral(yylval *parserSymType) int {
|
|||
|
||||
// If the string is empty, just skip it. We're still in
|
||||
// an interpolation so we do this to avoid empty nodes.
|
||||
if yylval.str == "" {
|
||||
return x.Lex(yylval)
|
||||
if yylval.token.Value.(string) == "" {
|
||||
return x.lex(yylval)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -113,8 +137,8 @@ func (x *parserLex) lexModeInterpolation(yylval *parserSymType) int {
|
|||
|
||||
// If the string is empty and we're starting an interpolation,
|
||||
// then just skip it to avoid empty string AST nodes
|
||||
if yylval.str == "" {
|
||||
return x.Lex(yylval)
|
||||
if yylval.token.Value.(string) == "" {
|
||||
return x.lex(yylval)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -165,7 +189,7 @@ func (x *parserLex) lexId(yylval *parserSymType) int {
|
|||
}
|
||||
}
|
||||
|
||||
yylval.str = b.String()
|
||||
yylval.token = &parserToken{Value: b.String()}
|
||||
return IDENTIFIER
|
||||
}
|
||||
|
||||
|
@ -224,7 +248,7 @@ func (x *parserLex) lexString(yylval *parserSymType, quoted bool) (int, bool) {
|
|||
}
|
||||
}
|
||||
|
||||
yylval.str = b.String()
|
||||
yylval.token = &parserToken{Value: b.String()}
|
||||
return STRING, terminated
|
||||
}
|
||||
|
||||
|
@ -238,6 +262,24 @@ func (x *parserLex) next() rune {
|
|||
r, w := utf8.DecodeRuneInString(x.Input[x.pos:])
|
||||
x.width = w
|
||||
x.pos += x.width
|
||||
|
||||
if x.line == 0 {
|
||||
x.line = 1
|
||||
x.col = 1
|
||||
} else {
|
||||
x.col += 1
|
||||
}
|
||||
|
||||
if r == '\n' {
|
||||
x.lastLine = x.col
|
||||
x.line += 1
|
||||
x.col = 1
|
||||
}
|
||||
|
||||
if x.astPos == nil {
|
||||
x.astPos = &ast.Pos{Column: x.col, Line: x.line}
|
||||
}
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
|
@ -251,6 +293,14 @@ func (x *parserLex) peek() rune {
|
|||
// backup steps back one rune. Can only be called once per next.
|
||||
func (x *parserLex) backup() {
|
||||
x.pos -= x.width
|
||||
x.col -= 1
|
||||
|
||||
// If we are at column 0, we're backing up across a line boundary
|
||||
// so we need to be careful to get the proper value.
|
||||
if x.col == 0 {
|
||||
x.col = x.lastLine
|
||||
x.line -= 1
|
||||
}
|
||||
}
|
||||
|
||||
// The parser calls this method on a parse error.
|
||||
|
|
|
@ -19,6 +19,7 @@ func TestParse(t *testing.T) {
|
|||
&ast.LiteralNode{
|
||||
Value: "foo",
|
||||
Type: ast.TypeString,
|
||||
Posx: ast.Pos{Column: 1, Line: 1},
|
||||
},
|
||||
},
|
||||
|
||||
|
@ -26,13 +27,16 @@ func TestParse(t *testing.T) {
|
|||
"foo ${var.bar}",
|
||||
false,
|
||||
&ast.Concat{
|
||||
Posx: ast.Pos{Column: 1, Line: 1},
|
||||
Exprs: []ast.Node{
|
||||
&ast.LiteralNode{
|
||||
Value: "foo ",
|
||||
Type: ast.TypeString,
|
||||
Posx: ast.Pos{Column: 1, Line: 1},
|
||||
},
|
||||
&ast.VariableAccess{
|
||||
Name: "var.bar",
|
||||
Posx: ast.Pos{Column: 7, Line: 1},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -42,17 +46,21 @@ func TestParse(t *testing.T) {
|
|||
"foo ${var.bar} baz",
|
||||
false,
|
||||
&ast.Concat{
|
||||
Posx: ast.Pos{Column: 1, Line: 1},
|
||||
Exprs: []ast.Node{
|
||||
&ast.LiteralNode{
|
||||
Value: "foo ",
|
||||
Type: ast.TypeString,
|
||||
Posx: ast.Pos{Column: 1, Line: 1},
|
||||
},
|
||||
&ast.VariableAccess{
|
||||
Name: "var.bar",
|
||||
Posx: ast.Pos{Column: 7, Line: 1},
|
||||
},
|
||||
&ast.LiteralNode{
|
||||
Value: " baz",
|
||||
Type: ast.TypeString,
|
||||
Posx: ast.Pos{Column: 15, Line: 1},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -62,14 +70,17 @@ func TestParse(t *testing.T) {
|
|||
"foo ${\"bar\"}",
|
||||
false,
|
||||
&ast.Concat{
|
||||
Posx: ast.Pos{Column: 1, Line: 1},
|
||||
Exprs: []ast.Node{
|
||||
&ast.LiteralNode{
|
||||
Value: "foo ",
|
||||
Type: ast.TypeString,
|
||||
Posx: ast.Pos{Column: 1, Line: 1},
|
||||
},
|
||||
&ast.LiteralNode{
|
||||
Value: "bar",
|
||||
Type: ast.TypeString,
|
||||
Posx: ast.Pos{Column: 7, Line: 1},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -81,6 +92,7 @@ func TestParse(t *testing.T) {
|
|||
&ast.Call{
|
||||
Func: "foo",
|
||||
Args: nil,
|
||||
Posx: ast.Pos{Column: 3, Line: 1},
|
||||
},
|
||||
},
|
||||
|
||||
|
@ -89,9 +101,11 @@ func TestParse(t *testing.T) {
|
|||
false,
|
||||
&ast.Call{
|
||||
Func: "foo",
|
||||
Posx: ast.Pos{Column: 3, Line: 1},
|
||||
Args: []ast.Node{
|
||||
&ast.VariableAccess{
|
||||
Name: "bar",
|
||||
Posx: ast.Pos{Column: 7, Line: 1},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -102,12 +116,15 @@ func TestParse(t *testing.T) {
|
|||
false,
|
||||
&ast.Call{
|
||||
Func: "foo",
|
||||
Posx: ast.Pos{Column: 3, Line: 1},
|
||||
Args: []ast.Node{
|
||||
&ast.VariableAccess{
|
||||
Name: "bar",
|
||||
Posx: ast.Pos{Column: 7, Line: 1},
|
||||
},
|
||||
&ast.VariableAccess{
|
||||
Name: "baz",
|
||||
Posx: ast.Pos{Column: 11, Line: 1},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -118,12 +135,15 @@ func TestParse(t *testing.T) {
|
|||
false,
|
||||
&ast.Call{
|
||||
Func: "foo",
|
||||
Posx: ast.Pos{Column: 3, Line: 1},
|
||||
Args: []ast.Node{
|
||||
&ast.Call{
|
||||
Func: "bar",
|
||||
Posx: ast.Pos{Column: 7, Line: 1},
|
||||
Args: []ast.Node{
|
||||
&ast.VariableAccess{
|
||||
Name: "baz",
|
||||
Posx: ast.Pos{Column: 11, Line: 1},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -135,19 +155,24 @@ func TestParse(t *testing.T) {
|
|||
`foo ${"bar ${baz}"}`,
|
||||
false,
|
||||
&ast.Concat{
|
||||
Posx: ast.Pos{Column: 1, Line: 1},
|
||||
Exprs: []ast.Node{
|
||||
&ast.LiteralNode{
|
||||
Value: "foo ",
|
||||
Type: ast.TypeString,
|
||||
Posx: ast.Pos{Column: 1, Line: 1},
|
||||
},
|
||||
&ast.Concat{
|
||||
Posx: ast.Pos{Column: 7, Line: 1},
|
||||
Exprs: []ast.Node{
|
||||
&ast.LiteralNode{
|
||||
Value: "bar ",
|
||||
Type: ast.TypeString,
|
||||
Posx: ast.Pos{Column: 7, Line: 1},
|
||||
},
|
||||
&ast.VariableAccess{
|
||||
Name: "baz",
|
||||
Posx: ast.Pos{Column: 14, Line: 1},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -41,7 +41,7 @@ func (v *TypeVisitor) visit(raw ast.Node) {
|
|||
case *ast.VariableAccess:
|
||||
v.visitVariableAccess(n)
|
||||
default:
|
||||
v.err = fmt.Errorf("unknown node: %#v", raw)
|
||||
v.createErr(n, fmt.Sprintf("unknown node: %#v", raw))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,7 +59,8 @@ func (v *TypeVisitor) visitConcat(n *ast.Concat) {
|
|||
// All concat args must be strings, so validate that
|
||||
for i, t := range types {
|
||||
if t != ast.TypeString {
|
||||
v.err = fmt.Errorf("%s: argument %d must be a sting", n, i+1)
|
||||
v.createErr(n, fmt.Sprintf(
|
||||
"argument %d must be a sting", n, i+1))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -76,7 +77,8 @@ func (v *TypeVisitor) visitVariableAccess(n *ast.VariableAccess) {
|
|||
// Look up the variable in the map
|
||||
variable, ok := v.VarMap[n.Name]
|
||||
if !ok {
|
||||
v.err = fmt.Errorf("unknown variable accessed: %s", n.Name)
|
||||
v.createErr(n, fmt.Sprintf(
|
||||
"unknown variable accessed: %s", n.Name))
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -84,6 +86,10 @@ func (v *TypeVisitor) visitVariableAccess(n *ast.VariableAccess) {
|
|||
v.stackPush(variable.Type)
|
||||
}
|
||||
|
||||
func (v *TypeVisitor) createErr(n ast.Node, str string) {
|
||||
v.err = fmt.Errorf("%s: %s", n.Pos(), str)
|
||||
}
|
||||
|
||||
func (v *TypeVisitor) reset() {
|
||||
v.stack = nil
|
||||
v.err = nil
|
||||
|
|
|
@ -14,21 +14,20 @@ type parserSymType struct {
|
|||
node ast.Node
|
||||
nodeList []ast.Node
|
||||
str string
|
||||
token *parserToken
|
||||
}
|
||||
|
||||
const STRING = 57346
|
||||
const IDENTIFIER = 57347
|
||||
const PROGRAM_BRACKET_LEFT = 57348
|
||||
const PROGRAM_BRACKET_RIGHT = 57349
|
||||
const PROGRAM_STRING_START = 57350
|
||||
const PROGRAM_STRING_END = 57351
|
||||
const PAREN_LEFT = 57352
|
||||
const PAREN_RIGHT = 57353
|
||||
const COMMA = 57354
|
||||
const PROGRAM_BRACKET_LEFT = 57346
|
||||
const PROGRAM_BRACKET_RIGHT = 57347
|
||||
const PROGRAM_STRING_START = 57348
|
||||
const PROGRAM_STRING_END = 57349
|
||||
const PAREN_LEFT = 57350
|
||||
const PAREN_RIGHT = 57351
|
||||
const COMMA = 57352
|
||||
const IDENTIFIER = 57353
|
||||
const STRING = 57354
|
||||
|
||||
var parserToknames = []string{
|
||||
"STRING",
|
||||
"IDENTIFIER",
|
||||
"PROGRAM_BRACKET_LEFT",
|
||||
"PROGRAM_BRACKET_RIGHT",
|
||||
"PROGRAM_STRING_START",
|
||||
|
@ -36,6 +35,8 @@ var parserToknames = []string{
|
|||
"PAREN_LEFT",
|
||||
"PAREN_RIGHT",
|
||||
"COMMA",
|
||||
"IDENTIFIER",
|
||||
"STRING",
|
||||
}
|
||||
var parserStatenames = []string{}
|
||||
|
||||
|
@ -43,7 +44,7 @@ const parserEofCode = 1
|
|||
const parserErrCode = 2
|
||||
const parserMaxDepth = 200
|
||||
|
||||
//line lang.y:103
|
||||
//line lang.y:111
|
||||
|
||||
//line yacctab:1
|
||||
var parserExca = []int{
|
||||
|
@ -62,18 +63,18 @@ const parserLast = 21
|
|||
|
||||
var parserAct = []int{
|
||||
|
||||
9, 16, 17, 13, 3, 12, 1, 8, 6, 11,
|
||||
7, 6, 14, 7, 15, 8, 10, 2, 18, 4,
|
||||
9, 7, 7, 13, 3, 16, 17, 8, 11, 6,
|
||||
6, 12, 10, 2, 15, 8, 1, 14, 18, 4,
|
||||
5,
|
||||
}
|
||||
var parserPact = []int{
|
||||
|
||||
7, -1000, 7, -1000, -1000, -1000, -1000, 4, -1000, -2,
|
||||
7, -7, -1000, 4, -10, -1000, -1000, 4, -1000,
|
||||
-2, -1000, -2, -1000, -1000, -1000, -1000, -3, -1000, 6,
|
||||
-2, -5, -1000, -3, -4, -1000, -1000, -3, -1000,
|
||||
}
|
||||
var parserPgo = []int{
|
||||
|
||||
0, 0, 20, 19, 16, 4, 12, 6,
|
||||
0, 0, 20, 19, 12, 4, 17, 16,
|
||||
}
|
||||
var parserR1 = []int{
|
||||
|
||||
|
@ -87,8 +88,8 @@ var parserR2 = []int{
|
|||
}
|
||||
var parserChk = []int{
|
||||
|
||||
-1000, -7, -4, -5, -3, -2, 4, 6, -5, -1,
|
||||
-4, 5, 7, 10, -6, -1, 11, 12, -1,
|
||||
-1000, -7, -4, -5, -3, -2, 12, 4, -5, -1,
|
||||
-4, 11, 5, 8, -6, -1, 9, 10, -1,
|
||||
}
|
||||
var parserDef = []int{
|
||||
|
||||
|
@ -334,17 +335,17 @@ parserdefault:
|
|||
switch parsernt {
|
||||
|
||||
case 1:
|
||||
//line lang.y:31
|
||||
//line lang.y:34
|
||||
{
|
||||
parserResult = parserS[parserpt-0].node
|
||||
}
|
||||
case 2:
|
||||
//line lang.y:37
|
||||
//line lang.y:40
|
||||
{
|
||||
parserVAL.node = parserS[parserpt-0].node
|
||||
}
|
||||
case 3:
|
||||
//line lang.y:41
|
||||
//line lang.y:44
|
||||
{
|
||||
var result []ast.Node
|
||||
if c, ok := parserS[parserpt-1].node.(*ast.Concat); ok {
|
||||
|
@ -355,57 +356,62 @@ parserdefault:
|
|||
|
||||
parserVAL.node = &ast.Concat{
|
||||
Exprs: result,
|
||||
Posx: result[0].Pos(),
|
||||
}
|
||||
}
|
||||
case 4:
|
||||
//line lang.y:56
|
||||
{
|
||||
parserVAL.node = parserS[parserpt-0].node
|
||||
}
|
||||
case 5:
|
||||
//line lang.y:60
|
||||
{
|
||||
parserVAL.node = parserS[parserpt-0].node
|
||||
}
|
||||
case 5:
|
||||
//line lang.y:64
|
||||
{
|
||||
parserVAL.node = parserS[parserpt-0].node
|
||||
}
|
||||
case 6:
|
||||
//line lang.y:66
|
||||
//line lang.y:70
|
||||
{
|
||||
parserVAL.node = parserS[parserpt-1].node
|
||||
}
|
||||
case 7:
|
||||
//line lang.y:72
|
||||
//line lang.y:76
|
||||
{
|
||||
parserVAL.node = parserS[parserpt-0].node
|
||||
}
|
||||
case 8:
|
||||
//line lang.y:76
|
||||
{
|
||||
parserVAL.node = &ast.VariableAccess{Name: parserS[parserpt-0].str}
|
||||
}
|
||||
case 9:
|
||||
//line lang.y:80
|
||||
{
|
||||
parserVAL.node = &ast.Call{Func: parserS[parserpt-3].str, Args: parserS[parserpt-1].nodeList}
|
||||
parserVAL.node = &ast.VariableAccess{Name: parserS[parserpt-0].token.Value.(string), Posx: parserS[parserpt-0].token.Pos}
|
||||
}
|
||||
case 9:
|
||||
//line lang.y:84
|
||||
{
|
||||
parserVAL.node = &ast.Call{Func: parserS[parserpt-3].token.Value.(string), Args: parserS[parserpt-1].nodeList, Posx: parserS[parserpt-3].token.Pos}
|
||||
}
|
||||
case 10:
|
||||
//line lang.y:85
|
||||
//line lang.y:89
|
||||
{
|
||||
parserVAL.nodeList = nil
|
||||
}
|
||||
case 11:
|
||||
//line lang.y:89
|
||||
//line lang.y:93
|
||||
{
|
||||
parserVAL.nodeList = append(parserS[parserpt-2].nodeList, parserS[parserpt-0].node)
|
||||
}
|
||||
case 12:
|
||||
//line lang.y:93
|
||||
//line lang.y:97
|
||||
{
|
||||
parserVAL.nodeList = append(parserVAL.nodeList, parserS[parserpt-0].node)
|
||||
}
|
||||
case 13:
|
||||
//line lang.y:99
|
||||
//line lang.y:103
|
||||
{
|
||||
parserVAL.node = &ast.LiteralNode{Value: parserS[parserpt-0].str, Type: ast.TypeString}
|
||||
parserVAL.node = &ast.LiteralNode{
|
||||
Value: parserS[parserpt-0].token.Value.(string),
|
||||
Type: ast.TypeString,
|
||||
Posx: parserS[parserpt-0].token.Pos,
|
||||
}
|
||||
}
|
||||
}
|
||||
goto parserstack /* stack new state and value */
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
state 0
|
||||
$accept: .top $end
|
||||
|
||||
STRING shift 6
|
||||
PROGRAM_BRACKET_LEFT shift 7
|
||||
STRING shift 6
|
||||
. error
|
||||
|
||||
interpolation goto 5
|
||||
|
@ -23,9 +23,9 @@ state 2
|
|||
top: literalModeTop. (1)
|
||||
literalModeTop: literalModeTop.literalModeValue
|
||||
|
||||
STRING shift 6
|
||||
PROGRAM_BRACKET_LEFT shift 7
|
||||
. reduce 1 (src line 29)
|
||||
STRING shift 6
|
||||
. reduce 1 (src line 32)
|
||||
|
||||
interpolation goto 5
|
||||
literal goto 4
|
||||
|
@ -34,33 +34,33 @@ state 2
|
|||
state 3
|
||||
literalModeTop: literalModeValue. (2)
|
||||
|
||||
. reduce 2 (src line 35)
|
||||
. reduce 2 (src line 38)
|
||||
|
||||
|
||||
state 4
|
||||
literalModeValue: literal. (4)
|
||||
|
||||
. reduce 4 (src line 54)
|
||||
. reduce 4 (src line 58)
|
||||
|
||||
|
||||
state 5
|
||||
literalModeValue: interpolation. (5)
|
||||
|
||||
. reduce 5 (src line 59)
|
||||
. reduce 5 (src line 63)
|
||||
|
||||
|
||||
state 6
|
||||
literal: STRING. (13)
|
||||
|
||||
. reduce 13 (src line 97)
|
||||
. reduce 13 (src line 101)
|
||||
|
||||
|
||||
state 7
|
||||
interpolation: PROGRAM_BRACKET_LEFT.expr PROGRAM_BRACKET_RIGHT
|
||||
|
||||
STRING shift 6
|
||||
IDENTIFIER shift 11
|
||||
PROGRAM_BRACKET_LEFT shift 7
|
||||
IDENTIFIER shift 11
|
||||
STRING shift 6
|
||||
. error
|
||||
|
||||
expr goto 9
|
||||
|
@ -72,7 +72,7 @@ state 7
|
|||
state 8
|
||||
literalModeTop: literalModeTop literalModeValue. (3)
|
||||
|
||||
. reduce 3 (src line 40)
|
||||
. reduce 3 (src line 43)
|
||||
|
||||
|
||||
state 9
|
||||
|
@ -86,9 +86,9 @@ state 10
|
|||
literalModeTop: literalModeTop.literalModeValue
|
||||
expr: literalModeTop. (7)
|
||||
|
||||
STRING shift 6
|
||||
PROGRAM_BRACKET_LEFT shift 7
|
||||
. reduce 7 (src line 70)
|
||||
STRING shift 6
|
||||
. reduce 7 (src line 74)
|
||||
|
||||
interpolation goto 5
|
||||
literal goto 4
|
||||
|
@ -99,23 +99,23 @@ state 11
|
|||
expr: IDENTIFIER.PAREN_LEFT args PAREN_RIGHT
|
||||
|
||||
PAREN_LEFT shift 13
|
||||
. reduce 8 (src line 75)
|
||||
. reduce 8 (src line 79)
|
||||
|
||||
|
||||
state 12
|
||||
interpolation: PROGRAM_BRACKET_LEFT expr PROGRAM_BRACKET_RIGHT. (6)
|
||||
|
||||
. reduce 6 (src line 64)
|
||||
. reduce 6 (src line 68)
|
||||
|
||||
|
||||
state 13
|
||||
expr: IDENTIFIER PAREN_LEFT.args PAREN_RIGHT
|
||||
args: . (10)
|
||||
|
||||
STRING shift 6
|
||||
IDENTIFIER shift 11
|
||||
PROGRAM_BRACKET_LEFT shift 7
|
||||
. reduce 10 (src line 84)
|
||||
IDENTIFIER shift 11
|
||||
STRING shift 6
|
||||
. reduce 10 (src line 88)
|
||||
|
||||
expr goto 15
|
||||
interpolation goto 5
|
||||
|
@ -136,21 +136,21 @@ state 14
|
|||
state 15
|
||||
args: expr. (12)
|
||||
|
||||
. reduce 12 (src line 92)
|
||||
. reduce 12 (src line 96)
|
||||
|
||||
|
||||
state 16
|
||||
expr: IDENTIFIER PAREN_LEFT args PAREN_RIGHT. (9)
|
||||
|
||||
. reduce 9 (src line 79)
|
||||
. reduce 9 (src line 83)
|
||||
|
||||
|
||||
state 17
|
||||
args: args COMMA.expr
|
||||
|
||||
STRING shift 6
|
||||
IDENTIFIER shift 11
|
||||
PROGRAM_BRACKET_LEFT shift 7
|
||||
IDENTIFIER shift 11
|
||||
STRING shift 6
|
||||
. error
|
||||
|
||||
expr goto 18
|
||||
|
@ -162,7 +162,7 @@ state 17
|
|||
state 18
|
||||
args: args COMMA expr. (11)
|
||||
|
||||
. reduce 11 (src line 88)
|
||||
. reduce 11 (src line 92)
|
||||
|
||||
|
||||
12 terminals, 8 nonterminals
|
||||
|
|
Loading…
Reference in New Issue