github.com/arvindram03/terraform@v0.3.7-0.20150212015210-408f838db36d/config/lang/lang.y (about)

     1  // This is the yacc input for creating the parser for interpolation
     2  // expressions in Go. To build it, just run `go generate` on this
     3  // package, as the lexer has the go generate pragma within it.
     4  
     5  %{
     6  package lang
     7  
     8  import (
     9      "github.com/hashicorp/terraform/config/lang/ast"
    10  )
    11  
    12  %}
    13  
    14  %union {
    15      node     ast.Node
    16      nodeList []ast.Node
    17      str      string
    18      token    *parserToken
    19  }
    20  
    21  %token  <str> PROGRAM_BRACKET_LEFT PROGRAM_BRACKET_RIGHT
    22  %token  <str> PROGRAM_STRING_START PROGRAM_STRING_END
    23  %token  <str> PAREN_LEFT PAREN_RIGHT COMMA
    24  
    25  %token <token> IDENTIFIER INTEGER FLOAT STRING
    26  
    27  %type <node> expr interpolation literal literalModeTop literalModeValue
    28  %type <nodeList> args
    29  
    30  %%
    31  
    32  top:
    33      {
    34          parserResult = &ast.LiteralNode{
    35              Value: "",
    36              Typex:  ast.TypeString,
    37              Posx:  ast.Pos{Column: 1, Line: 1},
    38          }
    39      }
    40  |   literalModeTop
    41  	{
    42          parserResult = $1
    43  
    44          // We want to make sure that the top value is always a Concat
    45          // so that the return value is always a string type from an
    46          // interpolation.
    47          //
    48          // The logic for checking for a LiteralNode is a little annoying
    49          // because functionally the AST is the same, but we do that because
    50          // it makes for an easy literal check later (to check if a string
    51          // has any interpolations).
    52          if _, ok := $1.(*ast.Concat); !ok {
    53              if n, ok := $1.(*ast.LiteralNode); !ok || n.Typex != ast.TypeString {
    54                  parserResult = &ast.Concat{
    55                      Exprs: []ast.Node{$1},
    56                      Posx:  $1.Pos(),
    57                  }
    58              }
    59          }
    60  	}
    61  
    62  literalModeTop:
    63      literalModeValue
    64      {
    65          $$ = $1
    66      }
    67  |   literalModeTop literalModeValue
    68      {
    69          var result []ast.Node
    70          if c, ok := $1.(*ast.Concat); ok {
    71              result = append(c.Exprs, $2)
    72          } else {
    73              result = []ast.Node{$1, $2}
    74          }
    75  
    76          $$ = &ast.Concat{
    77              Exprs: result,
    78              Posx:  result[0].Pos(),
    79          }
    80      }
    81  
    82  literalModeValue:
    83  	literal
    84  	{
    85          $$ = $1
    86  	}
    87  |   interpolation
    88      {
    89          $$ = $1
    90      }
    91  
    92  interpolation:
    93      PROGRAM_BRACKET_LEFT expr PROGRAM_BRACKET_RIGHT
    94      {
    95          $$ = $2
    96      }
    97  
    98  expr:
    99      literalModeTop
   100      {
   101          $$ = $1
   102      }
   103  |   INTEGER
   104      {
   105          $$ = &ast.LiteralNode{
   106              Value: $1.Value.(int),
   107              Typex:  ast.TypeInt,
   108              Posx:  $1.Pos,
   109          }
   110      }
   111  |   FLOAT
   112      {
   113          $$ = &ast.LiteralNode{
   114              Value: $1.Value.(float64),
   115              Typex:  ast.TypeFloat,
   116              Posx:  $1.Pos,
   117          }
   118      }
   119  |   IDENTIFIER
   120      {
   121          $$ = &ast.VariableAccess{Name: $1.Value.(string), Posx: $1.Pos}
   122      }
   123  |   IDENTIFIER PAREN_LEFT args PAREN_RIGHT
   124      {
   125          $$ = &ast.Call{Func: $1.Value.(string), Args: $3, Posx: $1.Pos}
   126      }
   127  
   128  args:
   129  	{
   130  		$$ = nil
   131  	}
   132  |	args COMMA expr
   133  	{
   134  		$$ = append($1, $3)
   135  	}
   136  |	expr
   137  	{
   138  		$$ = append($$, $1)
   139  	}
   140  
   141  literal:
   142      STRING
   143      {
   144          $$ = &ast.LiteralNode{
   145              Value: $1.Value.(string),
   146              Typex:  ast.TypeString,
   147              Posx:  $1.Pos,
   148          }
   149      }
   150  
   151  %%