Merge pull request #5348 from hashicorp/update-hil
dependencies: Update github.com/hashicorp/hil
This commit is contained in:
commit
3ea72e8b4c
|
@ -666,11 +666,11 @@
|
|||
},
|
||||
{
|
||||
"ImportPath": "github.com/hashicorp/hil",
|
||||
"Rev": "42518c6f01625b5e6948a6a0e6a0792df126c548"
|
||||
"Rev": "0457360d54ca4d081a769eaa1617e0462153fd70"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/hashicorp/hil/ast",
|
||||
"Rev": "42518c6f01625b5e6948a6a0e6a0792df126c548"
|
||||
"Rev": "0457360d54ca4d081a769eaa1617e0462153fd70"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/hashicorp/logutils",
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
.DS_Store
|
||||
.idea
|
||||
*.iml
|
||||
|
|
|
@ -52,4 +52,5 @@ const (
|
|||
TypeString
|
||||
TypeInt
|
||||
TypeFloat
|
||||
TypeList
|
||||
)
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
package ast
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Index represents an indexing operation into another data structure
|
||||
type Index struct {
|
||||
Target Node
|
||||
Key Node
|
||||
Posx Pos
|
||||
}
|
||||
|
||||
func (n *Index) Accept(v Visitor) Node {
|
||||
return v(n)
|
||||
}
|
||||
|
||||
func (n *Index) Pos() Pos {
|
||||
return n.Posx
|
||||
}
|
||||
|
||||
func (n *Index) String() string {
|
||||
return fmt.Sprintf("Index(%s, %s)", n.Target, n.Key)
|
||||
}
|
||||
|
||||
func (n *Index) Type(s Scope) (Type, error) {
|
||||
variableAccess, ok := n.Target.(*VariableAccess)
|
||||
if !ok {
|
||||
return TypeInvalid, fmt.Errorf("target is not a variable")
|
||||
}
|
||||
|
||||
variable, ok := s.LookupVar(variableAccess.Name)
|
||||
if !ok {
|
||||
return TypeInvalid, fmt.Errorf("unknown variable accessed: %s", variableAccess.Name)
|
||||
}
|
||||
if variable.Type != TypeList {
|
||||
return TypeInvalid, fmt.Errorf("invalid index operation into non-indexable type: %s", variable.Type)
|
||||
}
|
||||
|
||||
list := variable.Value.([]Variable)
|
||||
|
||||
// Ensure that the types of the list elements are homogenous
|
||||
listTypes := make(map[Type]struct{})
|
||||
for _, v := range list {
|
||||
if _, ok := listTypes[v.Type]; ok {
|
||||
continue
|
||||
}
|
||||
listTypes[v.Type] = struct{}{}
|
||||
}
|
||||
|
||||
if len(listTypes) != 1 {
|
||||
typesFound := make([]string, len(listTypes))
|
||||
i := 0
|
||||
for k, _ := range listTypes {
|
||||
typesFound[0] = k.String()
|
||||
i++
|
||||
}
|
||||
types := strings.Join(typesFound, ", ")
|
||||
return TypeInvalid, fmt.Errorf("list %q does not have homogenous types. found %s", variableAccess.Name, types)
|
||||
}
|
||||
|
||||
return list[0].Type, nil
|
||||
}
|
||||
|
||||
func (n *Index) GoString() string {
|
||||
return fmt.Sprintf("*%#v", *n)
|
||||
}
|
|
@ -1,5 +1,10 @@
|
|||
package ast
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// Scope is the interface used to look up variables and functions while
|
||||
// evaluating. How these functions/variables are defined are up to the caller.
|
||||
type Scope interface {
|
||||
|
@ -14,6 +19,26 @@ type Variable struct {
|
|||
Type Type
|
||||
}
|
||||
|
||||
// NewVariable creates a new Variable for the given value. This will
|
||||
// attempt to infer the correct type. If it can't, an error will be returned.
|
||||
func NewVariable(v interface{}) (result Variable, err error) {
|
||||
switch v := reflect.ValueOf(v); v.Kind() {
|
||||
case reflect.String:
|
||||
result.Type = TypeString
|
||||
default:
|
||||
err = fmt.Errorf("Unknown type: %s", v.Kind())
|
||||
}
|
||||
|
||||
result.Value = v
|
||||
return
|
||||
}
|
||||
|
||||
// String implements Stringer on Variable, displaying the type and value
|
||||
// of the Variable.
|
||||
func (v Variable) String() string {
|
||||
return fmt.Sprintf("{Variable (%s): %+v}", v.Type, v.Value)
|
||||
}
|
||||
|
||||
// Function defines a function that can be executed by the engine.
|
||||
// The type checker will validate that the proper types will be called
|
||||
// to the callback.
|
||||
|
|
|
@ -10,6 +10,7 @@ const (
|
|||
_Type_name_2 = "TypeString"
|
||||
_Type_name_3 = "TypeInt"
|
||||
_Type_name_4 = "TypeFloat"
|
||||
_Type_name_5 = "TypeList"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -18,6 +19,7 @@ var (
|
|||
_Type_index_2 = [...]uint8{0, 10}
|
||||
_Type_index_3 = [...]uint8{0, 7}
|
||||
_Type_index_4 = [...]uint8{0, 9}
|
||||
_Type_index_5 = [...]uint8{0, 8}
|
||||
)
|
||||
|
||||
func (i Type) String() string {
|
||||
|
@ -32,6 +34,8 @@ func (i Type) String() string {
|
|||
return _Type_name_3
|
||||
case i == 16:
|
||||
return _Type_name_4
|
||||
case i == 32:
|
||||
return _Type_name_5
|
||||
default:
|
||||
return fmt.Sprintf("Type(%d)", i)
|
||||
}
|
||||
|
|
|
@ -61,6 +61,9 @@ func (v *TypeCheck) visit(raw ast.Node) ast.Node {
|
|||
case *ast.Call:
|
||||
tc := &typeCheckCall{n}
|
||||
result, err = tc.TypeCheck(v)
|
||||
case *ast.Index:
|
||||
tc := &typeCheckIndex{n}
|
||||
result, err = tc.TypeCheck(v)
|
||||
case *ast.Concat:
|
||||
tc := &typeCheckConcat{n}
|
||||
result, err = tc.TypeCheck(v)
|
||||
|
@ -285,6 +288,55 @@ func (tc *typeCheckVariableAccess) TypeCheck(v *TypeCheck) (ast.Node, error) {
|
|||
return tc.n, nil
|
||||
}
|
||||
|
||||
type typeCheckIndex struct {
|
||||
n *ast.Index
|
||||
}
|
||||
|
||||
func (tc *typeCheckIndex) TypeCheck(v *TypeCheck) (ast.Node, error) {
|
||||
|
||||
value, err := tc.n.Key.Type(v.Scope)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if value != ast.TypeInt {
|
||||
return nil, fmt.Errorf("key of an index must be an int, was %s", value)
|
||||
}
|
||||
|
||||
// Ensure we have a VariableAccess as the target
|
||||
varAccessNode, ok := tc.n.Target.(*ast.VariableAccess)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("target of an index must be a VariableAccess node, was %T", tc.n.Target)
|
||||
}
|
||||
|
||||
// Get the variable
|
||||
variable, ok := v.Scope.LookupVar(varAccessNode.Name)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unknown variable accessed: %s", varAccessNode.Name)
|
||||
}
|
||||
if variable.Type != ast.TypeList {
|
||||
return nil, fmt.Errorf("invalid index operation into non-indexable type: %s", variable.Type)
|
||||
}
|
||||
|
||||
list := variable.Value.([]ast.Variable)
|
||||
|
||||
// Ensure that the types of the list elements are homogenous
|
||||
listTypes := make(map[ast.Type]struct{})
|
||||
for _, v := range list {
|
||||
if _, ok := listTypes[v.Type]; ok {
|
||||
continue
|
||||
}
|
||||
listTypes[v.Type] = struct{}{}
|
||||
}
|
||||
|
||||
if len(listTypes) != 1 {
|
||||
return nil, fmt.Errorf("list %q does not have homogenous types (%s)", varAccessNode.Name)
|
||||
}
|
||||
|
||||
// This is the type since the list is homogenous in type
|
||||
v.StackPush(list[0].Type)
|
||||
return tc.n, nil
|
||||
}
|
||||
|
||||
func (v *TypeCheck) ImplicitConversion(
|
||||
actual ast.Type, expected ast.Type, n ast.Node) ast.Node {
|
||||
if v.Implicit == nil {
|
||||
|
|
|
@ -140,6 +140,8 @@ func (v *evalVisitor) visit(raw ast.Node) ast.Node {
|
|||
// types as well as any other EvalNode implementations.
|
||||
func evalNode(raw ast.Node) (EvalNode, error) {
|
||||
switch n := raw.(type) {
|
||||
case *ast.Index:
|
||||
return &evalIndex{n}, nil
|
||||
case *ast.Call:
|
||||
return &evalCall{n}, nil
|
||||
case *ast.Concat:
|
||||
|
@ -184,6 +186,53 @@ func (v *evalCall) Eval(s ast.Scope, stack *ast.Stack) (interface{}, ast.Type, e
|
|||
return result, function.ReturnType, nil
|
||||
}
|
||||
|
||||
type evalIndex struct{ *ast.Index }
|
||||
|
||||
func (v *evalIndex) Eval(scope ast.Scope, stack *ast.Stack) (interface{}, ast.Type, error) {
|
||||
evalVarAccess, err := evalNode(v.Target)
|
||||
if err != nil {
|
||||
return nil, ast.TypeInvalid, err
|
||||
}
|
||||
target, targetType, err := evalVarAccess.Eval(scope, stack)
|
||||
|
||||
evalKey, err := evalNode(v.Key)
|
||||
if err != nil {
|
||||
return nil, ast.TypeInvalid, err
|
||||
}
|
||||
key, keyType, err := evalKey.Eval(scope, stack)
|
||||
|
||||
// Last sanity check
|
||||
if targetType != ast.TypeList {
|
||||
return nil, ast.TypeInvalid, fmt.Errorf("target for indexing must be ast.TypeList, is %s", targetType)
|
||||
}
|
||||
if keyType != ast.TypeInt {
|
||||
return nil, ast.TypeInvalid, fmt.Errorf("key for indexing must be ast.TypeInt, is %s", keyType)
|
||||
}
|
||||
|
||||
list, ok := target.([]ast.Variable)
|
||||
if !ok {
|
||||
return nil, ast.TypeInvalid, fmt.Errorf("cannot cast target to []Variable")
|
||||
}
|
||||
|
||||
keyInt, ok := key.(int)
|
||||
if !ok {
|
||||
return nil, ast.TypeInvalid, fmt.Errorf("cannot cast key to int")
|
||||
}
|
||||
|
||||
if len(list) == 0 {
|
||||
return nil, ast.TypeInvalid, fmt.Errorf("list is empty")
|
||||
}
|
||||
|
||||
if keyInt < 0 || len(list) < keyInt+1 {
|
||||
return nil, ast.TypeInvalid, fmt.Errorf("index %d out of range (max %d)", keyInt, len(list))
|
||||
}
|
||||
|
||||
returnVal := list[keyInt].Value
|
||||
returnType := list[keyInt].Type
|
||||
|
||||
return returnVal, returnType, nil
|
||||
}
|
||||
|
||||
type evalConcat struct{ *ast.Concat }
|
||||
|
||||
func (v *evalConcat) Eval(s ast.Scope, stack *ast.Stack) (interface{}, ast.Type, error) {
|
||||
|
|
|
@ -21,6 +21,7 @@ import (
|
|||
%token <str> PROGRAM_BRACKET_LEFT PROGRAM_BRACKET_RIGHT
|
||||
%token <str> PROGRAM_STRING_START PROGRAM_STRING_END
|
||||
%token <str> PAREN_LEFT PAREN_RIGHT COMMA
|
||||
%token <str> SQUARE_BRACKET_LEFT SQUARE_BRACKET_RIGHT
|
||||
|
||||
%token <token> ARITH_OP IDENTIFIER INTEGER FLOAT STRING
|
||||
|
||||
|
@ -157,6 +158,17 @@ expr:
|
|||
{
|
||||
$$ = &ast.Call{Func: $1.Value.(string), Args: $3, Posx: $1.Pos}
|
||||
}
|
||||
| IDENTIFIER SQUARE_BRACKET_LEFT expr SQUARE_BRACKET_RIGHT
|
||||
{
|
||||
$$ = &ast.Index{
|
||||
Target: &ast.VariableAccess{
|
||||
Name: $1.Value.(string),
|
||||
Posx: $1.Pos,
|
||||
},
|
||||
Key: $3,
|
||||
Posx: $1.Pos,
|
||||
}
|
||||
}
|
||||
|
||||
args:
|
||||
{
|
||||
|
|
|
@ -166,6 +166,10 @@ func (x *parserLex) lexModeInterpolation(yylval *parserSymType) int {
|
|||
return PAREN_LEFT
|
||||
case ')':
|
||||
return PAREN_RIGHT
|
||||
case '[':
|
||||
return SQUARE_BRACKET_LEFT
|
||||
case ']':
|
||||
return SQUARE_BRACKET_RIGHT
|
||||
case ',':
|
||||
return COMMA
|
||||
case '+':
|
||||
|
|
|
@ -24,11 +24,13 @@ const PROGRAM_STRING_END = 57349
|
|||
const PAREN_LEFT = 57350
|
||||
const PAREN_RIGHT = 57351
|
||||
const COMMA = 57352
|
||||
const ARITH_OP = 57353
|
||||
const IDENTIFIER = 57354
|
||||
const INTEGER = 57355
|
||||
const FLOAT = 57356
|
||||
const STRING = 57357
|
||||
const SQUARE_BRACKET_LEFT = 57353
|
||||
const SQUARE_BRACKET_RIGHT = 57354
|
||||
const ARITH_OP = 57355
|
||||
const IDENTIFIER = 57356
|
||||
const INTEGER = 57357
|
||||
const FLOAT = 57358
|
||||
const STRING = 57359
|
||||
|
||||
var parserToknames = [...]string{
|
||||
"$end",
|
||||
|
@ -41,6 +43,8 @@ var parserToknames = [...]string{
|
|||
"PAREN_LEFT",
|
||||
"PAREN_RIGHT",
|
||||
"COMMA",
|
||||
"SQUARE_BRACKET_LEFT",
|
||||
"SQUARE_BRACKET_RIGHT",
|
||||
"ARITH_OP",
|
||||
"IDENTIFIER",
|
||||
"INTEGER",
|
||||
|
@ -53,7 +57,7 @@ const parserEofCode = 1
|
|||
const parserErrCode = 2
|
||||
const parserMaxDepth = 200
|
||||
|
||||
//line lang.y:184
|
||||
//line lang.y:196
|
||||
|
||||
//line yacctab:1
|
||||
var parserExca = [...]int{
|
||||
|
@ -62,52 +66,57 @@ var parserExca = [...]int{
|
|||
-2, 0,
|
||||
}
|
||||
|
||||
const parserNprod = 20
|
||||
const parserNprod = 21
|
||||
const parserPrivate = 57344
|
||||
|
||||
var parserTokenNames []string
|
||||
var parserStates []string
|
||||
|
||||
const parserLast = 34
|
||||
const parserLast = 37
|
||||
|
||||
var parserAct = [...]int{
|
||||
|
||||
9, 7, 3, 16, 22, 8, 17, 17, 20, 17,
|
||||
1, 18, 6, 23, 8, 19, 25, 26, 21, 11,
|
||||
2, 24, 7, 4, 5, 0, 10, 27, 0, 14,
|
||||
15, 12, 13, 6,
|
||||
9, 7, 29, 17, 23, 16, 17, 3, 17, 20,
|
||||
8, 18, 21, 17, 6, 19, 27, 28, 22, 8,
|
||||
1, 25, 26, 7, 11, 2, 24, 10, 4, 30,
|
||||
5, 0, 14, 15, 12, 13, 6,
|
||||
}
|
||||
var parserPact = [...]int{
|
||||
|
||||
-3, -1000, -3, -1000, -1000, -1000, -1000, 18, -1000, -2,
|
||||
18, -3, -1000, -1000, 18, 0, -1000, 18, -5, -1000,
|
||||
18, -1000, -1000, 7, -4, -1000, 18, -4,
|
||||
-3, -1000, -3, -1000, -1000, -1000, -1000, 19, -1000, 0,
|
||||
19, -3, -1000, -1000, 19, 1, -1000, 19, -5, -1000,
|
||||
19, 19, -1000, -1000, 7, -7, -10, -1000, 19, -1000,
|
||||
-7,
|
||||
}
|
||||
var parserPgo = [...]int{
|
||||
|
||||
0, 0, 24, 23, 19, 2, 13, 10,
|
||||
0, 0, 30, 28, 24, 7, 26, 20,
|
||||
}
|
||||
var parserR1 = [...]int{
|
||||
|
||||
0, 7, 7, 4, 4, 5, 5, 2, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 6, 6, 6, 3,
|
||||
1, 1, 1, 1, 1, 1, 1, 6, 6, 6,
|
||||
3,
|
||||
}
|
||||
var parserR2 = [...]int{
|
||||
|
||||
0, 0, 1, 1, 2, 1, 1, 3, 3, 1,
|
||||
1, 1, 2, 3, 1, 4, 0, 3, 1, 1,
|
||||
1, 1, 2, 3, 1, 4, 4, 0, 3, 1,
|
||||
1,
|
||||
}
|
||||
var parserChk = [...]int{
|
||||
|
||||
-1000, -7, -4, -5, -3, -2, 15, 4, -5, -1,
|
||||
8, -4, 13, 14, 11, 12, 5, 11, -1, -1,
|
||||
8, -1, 9, -6, -1, 9, 10, -1,
|
||||
-1000, -7, -4, -5, -3, -2, 17, 4, -5, -1,
|
||||
8, -4, 15, 16, 13, 14, 5, 13, -1, -1,
|
||||
8, 11, -1, 9, -6, -1, -1, 9, 10, 12,
|
||||
-1,
|
||||
}
|
||||
var parserDef = [...]int{
|
||||
|
||||
1, -2, 2, 3, 5, 6, 19, 0, 4, 0,
|
||||
1, -2, 2, 3, 5, 6, 20, 0, 4, 0,
|
||||
0, 9, 10, 11, 0, 14, 7, 0, 0, 12,
|
||||
16, 13, 8, 0, 18, 15, 0, 17,
|
||||
17, 0, 13, 8, 0, 19, 0, 15, 0, 16,
|
||||
18,
|
||||
}
|
||||
var parserTok1 = [...]int{
|
||||
|
||||
|
@ -116,7 +125,7 @@ var parserTok1 = [...]int{
|
|||
var parserTok2 = [...]int{
|
||||
|
||||
2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
|
||||
12, 13, 14, 15,
|
||||
12, 13, 14, 15, 16, 17,
|
||||
}
|
||||
var parserTok3 = [...]int{
|
||||
0,
|
||||
|
@ -464,7 +473,7 @@ parserdefault:
|
|||
|
||||
case 1:
|
||||
parserDollar = parserS[parserpt-0 : parserpt+1]
|
||||
//line lang.y:35
|
||||
//line lang.y:36
|
||||
{
|
||||
parserResult = &ast.LiteralNode{
|
||||
Value: "",
|
||||
|
@ -474,7 +483,7 @@ parserdefault:
|
|||
}
|
||||
case 2:
|
||||
parserDollar = parserS[parserpt-1 : parserpt+1]
|
||||
//line lang.y:43
|
||||
//line lang.y:44
|
||||
{
|
||||
parserResult = parserDollar[1].node
|
||||
|
||||
|
@ -497,13 +506,13 @@ parserdefault:
|
|||
}
|
||||
case 3:
|
||||
parserDollar = parserS[parserpt-1 : parserpt+1]
|
||||
//line lang.y:66
|
||||
//line lang.y:67
|
||||
{
|
||||
parserVAL.node = parserDollar[1].node
|
||||
}
|
||||
case 4:
|
||||
parserDollar = parserS[parserpt-2 : parserpt+1]
|
||||
//line lang.y:70
|
||||
//line lang.y:71
|
||||
{
|
||||
var result []ast.Node
|
||||
if c, ok := parserDollar[1].node.(*ast.Concat); ok {
|
||||
|
@ -519,37 +528,37 @@ parserdefault:
|
|||
}
|
||||
case 5:
|
||||
parserDollar = parserS[parserpt-1 : parserpt+1]
|
||||
//line lang.y:86
|
||||
//line lang.y:87
|
||||
{
|
||||
parserVAL.node = parserDollar[1].node
|
||||
}
|
||||
case 6:
|
||||
parserDollar = parserS[parserpt-1 : parserpt+1]
|
||||
//line lang.y:90
|
||||
//line lang.y:91
|
||||
{
|
||||
parserVAL.node = parserDollar[1].node
|
||||
}
|
||||
case 7:
|
||||
parserDollar = parserS[parserpt-3 : parserpt+1]
|
||||
//line lang.y:96
|
||||
//line lang.y:97
|
||||
{
|
||||
parserVAL.node = parserDollar[2].node
|
||||
}
|
||||
case 8:
|
||||
parserDollar = parserS[parserpt-3 : parserpt+1]
|
||||
//line lang.y:102
|
||||
//line lang.y:103
|
||||
{
|
||||
parserVAL.node = parserDollar[2].node
|
||||
}
|
||||
case 9:
|
||||
parserDollar = parserS[parserpt-1 : parserpt+1]
|
||||
//line lang.y:106
|
||||
//line lang.y:107
|
||||
{
|
||||
parserVAL.node = parserDollar[1].node
|
||||
}
|
||||
case 10:
|
||||
parserDollar = parserS[parserpt-1 : parserpt+1]
|
||||
//line lang.y:110
|
||||
//line lang.y:111
|
||||
{
|
||||
parserVAL.node = &ast.LiteralNode{
|
||||
Value: parserDollar[1].token.Value.(int),
|
||||
|
@ -559,7 +568,7 @@ parserdefault:
|
|||
}
|
||||
case 11:
|
||||
parserDollar = parserS[parserpt-1 : parserpt+1]
|
||||
//line lang.y:118
|
||||
//line lang.y:119
|
||||
{
|
||||
parserVAL.node = &ast.LiteralNode{
|
||||
Value: parserDollar[1].token.Value.(float64),
|
||||
|
@ -569,7 +578,7 @@ parserdefault:
|
|||
}
|
||||
case 12:
|
||||
parserDollar = parserS[parserpt-2 : parserpt+1]
|
||||
//line lang.y:126
|
||||
//line lang.y:127
|
||||
{
|
||||
// This is REALLY jank. We assume that a singular ARITH_OP
|
||||
// means 0 ARITH_OP expr, which... is weird. We don't want to
|
||||
|
@ -590,7 +599,7 @@ parserdefault:
|
|||
}
|
||||
case 13:
|
||||
parserDollar = parserS[parserpt-3 : parserpt+1]
|
||||
//line lang.y:145
|
||||
//line lang.y:146
|
||||
{
|
||||
parserVAL.node = &ast.Arithmetic{
|
||||
Op: parserDollar[2].token.Value.(ast.ArithmeticOp),
|
||||
|
@ -600,37 +609,50 @@ parserdefault:
|
|||
}
|
||||
case 14:
|
||||
parserDollar = parserS[parserpt-1 : parserpt+1]
|
||||
//line lang.y:153
|
||||
//line lang.y:154
|
||||
{
|
||||
parserVAL.node = &ast.VariableAccess{Name: parserDollar[1].token.Value.(string), Posx: parserDollar[1].token.Pos}
|
||||
}
|
||||
case 15:
|
||||
parserDollar = parserS[parserpt-4 : parserpt+1]
|
||||
//line lang.y:157
|
||||
//line lang.y:158
|
||||
{
|
||||
parserVAL.node = &ast.Call{Func: parserDollar[1].token.Value.(string), Args: parserDollar[3].nodeList, Posx: parserDollar[1].token.Pos}
|
||||
}
|
||||
case 16:
|
||||
parserDollar = parserS[parserpt-0 : parserpt+1]
|
||||
parserDollar = parserS[parserpt-4 : parserpt+1]
|
||||
//line lang.y:162
|
||||
{
|
||||
parserVAL.node = &ast.Index{
|
||||
Target: &ast.VariableAccess{
|
||||
Name: parserDollar[1].token.Value.(string),
|
||||
Posx: parserDollar[1].token.Pos,
|
||||
},
|
||||
Key: parserDollar[3].node,
|
||||
Posx: parserDollar[1].token.Pos,
|
||||
}
|
||||
}
|
||||
case 17:
|
||||
parserDollar = parserS[parserpt-0 : parserpt+1]
|
||||
//line lang.y:174
|
||||
{
|
||||
parserVAL.nodeList = nil
|
||||
}
|
||||
case 17:
|
||||
case 18:
|
||||
parserDollar = parserS[parserpt-3 : parserpt+1]
|
||||
//line lang.y:166
|
||||
//line lang.y:178
|
||||
{
|
||||
parserVAL.nodeList = append(parserDollar[1].nodeList, parserDollar[3].node)
|
||||
}
|
||||
case 18:
|
||||
case 19:
|
||||
parserDollar = parserS[parserpt-1 : parserpt+1]
|
||||
//line lang.y:170
|
||||
//line lang.y:182
|
||||
{
|
||||
parserVAL.nodeList = append(parserVAL.nodeList, parserDollar[1].node)
|
||||
}
|
||||
case 19:
|
||||
case 20:
|
||||
parserDollar = parserS[parserpt-1 : parserpt+1]
|
||||
//line lang.y:176
|
||||
//line lang.y:188
|
||||
{
|
||||
parserVAL.node = &ast.LiteralNode{
|
||||
Value: parserDollar[1].token.Value.(string),
|
||||
|
|
|
@ -5,7 +5,7 @@ state 0
|
|||
|
||||
PROGRAM_BRACKET_LEFT shift 7
|
||||
STRING shift 6
|
||||
. reduce 1 (src line 34)
|
||||
. reduce 1 (src line 35)
|
||||
|
||||
interpolation goto 5
|
||||
literal goto 4
|
||||
|
@ -26,7 +26,7 @@ state 2
|
|||
|
||||
PROGRAM_BRACKET_LEFT shift 7
|
||||
STRING shift 6
|
||||
. reduce 2 (src line 42)
|
||||
. reduce 2 (src line 43)
|
||||
|
||||
interpolation goto 5
|
||||
literal goto 4
|
||||
|
@ -35,25 +35,25 @@ state 2
|
|||
state 3
|
||||
literalModeTop: literalModeValue. (3)
|
||||
|
||||
. reduce 3 (src line 64)
|
||||
. reduce 3 (src line 65)
|
||||
|
||||
|
||||
state 4
|
||||
literalModeValue: literal. (5)
|
||||
|
||||
. reduce 5 (src line 84)
|
||||
. reduce 5 (src line 85)
|
||||
|
||||
|
||||
state 5
|
||||
literalModeValue: interpolation. (6)
|
||||
|
||||
. reduce 6 (src line 89)
|
||||
. reduce 6 (src line 90)
|
||||
|
||||
|
||||
state 6
|
||||
literal: STRING. (19)
|
||||
literal: STRING. (20)
|
||||
|
||||
. reduce 19 (src line 174)
|
||||
. reduce 20 (src line 186)
|
||||
|
||||
|
||||
state 7
|
||||
|
@ -77,7 +77,7 @@ state 7
|
|||
state 8
|
||||
literalModeTop: literalModeTop literalModeValue. (4)
|
||||
|
||||
. reduce 4 (src line 69)
|
||||
. reduce 4 (src line 70)
|
||||
|
||||
|
||||
state 9
|
||||
|
@ -113,7 +113,7 @@ state 11
|
|||
|
||||
PROGRAM_BRACKET_LEFT shift 7
|
||||
STRING shift 6
|
||||
. reduce 9 (src line 105)
|
||||
. reduce 9 (src line 106)
|
||||
|
||||
interpolation goto 5
|
||||
literal goto 4
|
||||
|
@ -122,13 +122,13 @@ state 11
|
|||
state 12
|
||||
expr: INTEGER. (10)
|
||||
|
||||
. reduce 10 (src line 109)
|
||||
. reduce 10 (src line 110)
|
||||
|
||||
|
||||
state 13
|
||||
expr: FLOAT. (11)
|
||||
|
||||
. reduce 11 (src line 117)
|
||||
. reduce 11 (src line 118)
|
||||
|
||||
|
||||
state 14
|
||||
|
@ -152,15 +152,17 @@ state 14
|
|||
state 15
|
||||
expr: IDENTIFIER. (14)
|
||||
expr: IDENTIFIER.PAREN_LEFT args PAREN_RIGHT
|
||||
expr: IDENTIFIER.SQUARE_BRACKET_LEFT expr SQUARE_BRACKET_RIGHT
|
||||
|
||||
PAREN_LEFT shift 20
|
||||
. reduce 14 (src line 152)
|
||||
SQUARE_BRACKET_LEFT shift 21
|
||||
. reduce 14 (src line 153)
|
||||
|
||||
|
||||
state 16
|
||||
interpolation: PROGRAM_BRACKET_LEFT expr PROGRAM_BRACKET_RIGHT. (7)
|
||||
|
||||
. reduce 7 (src line 94)
|
||||
. reduce 7 (src line 95)
|
||||
|
||||
|
||||
state 17
|
||||
|
@ -175,7 +177,7 @@ state 17
|
|||
STRING shift 6
|
||||
. error
|
||||
|
||||
expr goto 21
|
||||
expr goto 22
|
||||
interpolation goto 5
|
||||
literal goto 4
|
||||
literalModeTop goto 11
|
||||
|
@ -185,7 +187,7 @@ state 18
|
|||
expr: PAREN_LEFT expr.PAREN_RIGHT
|
||||
expr: expr.ARITH_OP expr
|
||||
|
||||
PAREN_RIGHT shift 22
|
||||
PAREN_RIGHT shift 23
|
||||
ARITH_OP shift 17
|
||||
. error
|
||||
|
||||
|
@ -194,12 +196,12 @@ state 19
|
|||
expr: ARITH_OP expr. (12)
|
||||
expr: expr.ARITH_OP expr
|
||||
|
||||
. reduce 12 (src line 125)
|
||||
. reduce 12 (src line 126)
|
||||
|
||||
|
||||
state 20
|
||||
expr: IDENTIFIER PAREN_LEFT.args PAREN_RIGHT
|
||||
args: . (16)
|
||||
args: . (17)
|
||||
|
||||
PROGRAM_BRACKET_LEFT shift 7
|
||||
PAREN_LEFT shift 10
|
||||
|
@ -208,52 +210,79 @@ state 20
|
|||
INTEGER shift 12
|
||||
FLOAT shift 13
|
||||
STRING shift 6
|
||||
. reduce 16 (src line 161)
|
||||
. reduce 17 (src line 173)
|
||||
|
||||
expr goto 24
|
||||
expr goto 25
|
||||
interpolation goto 5
|
||||
literal goto 4
|
||||
literalModeTop goto 11
|
||||
literalModeValue goto 3
|
||||
args goto 23
|
||||
args goto 24
|
||||
|
||||
state 21
|
||||
expr: IDENTIFIER SQUARE_BRACKET_LEFT.expr SQUARE_BRACKET_RIGHT
|
||||
|
||||
PROGRAM_BRACKET_LEFT shift 7
|
||||
PAREN_LEFT shift 10
|
||||
ARITH_OP shift 14
|
||||
IDENTIFIER shift 15
|
||||
INTEGER shift 12
|
||||
FLOAT shift 13
|
||||
STRING shift 6
|
||||
. error
|
||||
|
||||
expr goto 26
|
||||
interpolation goto 5
|
||||
literal goto 4
|
||||
literalModeTop goto 11
|
||||
literalModeValue goto 3
|
||||
|
||||
state 22
|
||||
expr: expr.ARITH_OP expr
|
||||
expr: expr ARITH_OP expr. (13)
|
||||
|
||||
. reduce 13 (src line 144)
|
||||
|
||||
|
||||
state 22
|
||||
expr: PAREN_LEFT expr PAREN_RIGHT. (8)
|
||||
|
||||
. reduce 8 (src line 100)
|
||||
. reduce 13 (src line 145)
|
||||
|
||||
|
||||
state 23
|
||||
expr: IDENTIFIER PAREN_LEFT args.PAREN_RIGHT
|
||||
args: args.COMMA expr
|
||||
expr: PAREN_LEFT expr PAREN_RIGHT. (8)
|
||||
|
||||
PAREN_RIGHT shift 25
|
||||
COMMA shift 26
|
||||
. error
|
||||
. reduce 8 (src line 101)
|
||||
|
||||
|
||||
state 24
|
||||
expr: expr.ARITH_OP expr
|
||||
args: expr. (18)
|
||||
expr: IDENTIFIER PAREN_LEFT args.PAREN_RIGHT
|
||||
args: args.COMMA expr
|
||||
|
||||
ARITH_OP shift 17
|
||||
. reduce 18 (src line 169)
|
||||
PAREN_RIGHT shift 27
|
||||
COMMA shift 28
|
||||
. error
|
||||
|
||||
|
||||
state 25
|
||||
expr: IDENTIFIER PAREN_LEFT args PAREN_RIGHT. (15)
|
||||
expr: expr.ARITH_OP expr
|
||||
args: expr. (19)
|
||||
|
||||
. reduce 15 (src line 156)
|
||||
ARITH_OP shift 17
|
||||
. reduce 19 (src line 181)
|
||||
|
||||
|
||||
state 26
|
||||
expr: expr.ARITH_OP expr
|
||||
expr: IDENTIFIER SQUARE_BRACKET_LEFT expr.SQUARE_BRACKET_RIGHT
|
||||
|
||||
SQUARE_BRACKET_RIGHT shift 29
|
||||
ARITH_OP shift 17
|
||||
. error
|
||||
|
||||
|
||||
state 27
|
||||
expr: IDENTIFIER PAREN_LEFT args PAREN_RIGHT. (15)
|
||||
|
||||
. reduce 15 (src line 157)
|
||||
|
||||
|
||||
state 28
|
||||
args: args COMMA.expr
|
||||
|
||||
PROGRAM_BRACKET_LEFT shift 7
|
||||
|
@ -265,29 +294,35 @@ state 26
|
|||
STRING shift 6
|
||||
. error
|
||||
|
||||
expr goto 27
|
||||
expr goto 30
|
||||
interpolation goto 5
|
||||
literal goto 4
|
||||
literalModeTop goto 11
|
||||
literalModeValue goto 3
|
||||
|
||||
state 27
|
||||
state 29
|
||||
expr: IDENTIFIER SQUARE_BRACKET_LEFT expr SQUARE_BRACKET_RIGHT. (16)
|
||||
|
||||
. reduce 16 (src line 161)
|
||||
|
||||
|
||||
state 30
|
||||
expr: expr.ARITH_OP expr
|
||||
args: args COMMA expr. (17)
|
||||
args: args COMMA expr. (18)
|
||||
|
||||
ARITH_OP shift 17
|
||||
. reduce 17 (src line 165)
|
||||
. reduce 18 (src line 177)
|
||||
|
||||
|
||||
15 terminals, 8 nonterminals
|
||||
20 grammar rules, 28/2000 states
|
||||
17 terminals, 8 nonterminals
|
||||
21 grammar rules, 31/2000 states
|
||||
0 shift/reduce, 0 reduce/reduce conflicts reported
|
||||
57 working sets used
|
||||
memory: parser 40/30000
|
||||
23 extra closures
|
||||
57 shift entries, 1 exceptions
|
||||
15 goto entries
|
||||
27 entries saved by goto default
|
||||
Optimizer space used: output 34/30000
|
||||
34 table entries, 2 zero
|
||||
maximum spread: 15, maximum offset: 26
|
||||
memory: parser 45/30000
|
||||
26 extra closures
|
||||
67 shift entries, 1 exceptions
|
||||
16 goto entries
|
||||
31 entries saved by goto default
|
||||
Optimizer space used: output 37/30000
|
||||
37 table entries, 1 zero
|
||||
maximum spread: 17, maximum offset: 28
|
||||
|
|
Loading…
Reference in New Issue