|
| 1 | +// ============================================================================ |
| 2 | +// Terminals |
| 3 | +// ============================================================================ |
| 4 | + |
| 5 | +// Whitespace and Comments |
| 6 | +NL_OR_COMMENT: /\n[ \t]*/ | /#.*\n/ | /\/\/.*\n/ | /\/\*(.|\n)*?(\*\/)/ |
| 7 | + |
| 8 | +// Keywords |
| 9 | +IF : "if" |
| 10 | +IN : "in" |
| 11 | +FOR : "for" |
| 12 | +FOR_EACH : "for_each" |
| 13 | + |
| 14 | +// Identifiers and Names |
| 15 | +NAME : /[a-zA-Z_][a-zA-Z0-9_-]*/ |
| 16 | +IDENTIFIER: NAME | IN | FOR | IF | FOR_EACH |
| 17 | + |
| 18 | +// Literals |
| 19 | +ESCAPED_INTERPOLATION.2: /\$\$\{[^}]*\}/ |
| 20 | +STRING_CHARS.1: /(?:(?!\$\$\{)(?!\$\{)[^"\\]|\\.|(?:\$(?!\$?\{)))+/ |
| 21 | +DECIMAL : "0".."9" |
| 22 | +NEGATIVE_DECIMAL : "-" DECIMAL |
| 23 | +EXP_MARK : ("e" | "E") ("+" | "-")? DECIMAL+ |
| 24 | +INT_LITERAL: NEGATIVE_DECIMAL? DECIMAL+ |
| 25 | +FLOAT_LITERAL: (NEGATIVE_DECIMAL? DECIMAL+ | NEGATIVE_DECIMAL+) "." DECIMAL+ (EXP_MARK)? |
| 26 | + | (NEGATIVE_DECIMAL? DECIMAL+ | NEGATIVE_DECIMAL+) (EXP_MARK) |
| 27 | + |
| 28 | +// Operators |
| 29 | +BINARY_OP : DOUBLE_EQ | NEQ | LT | GT | LEQ | GEQ | MINUS | ASTERISK | SLASH | PERCENT | DOUBLE_AMP | DOUBLE_PIPE | PLUS |
| 30 | +DOUBLE_EQ : "==" |
| 31 | +NEQ : "!=" |
| 32 | +LT : "<" |
| 33 | +GT : ">" |
| 34 | +LEQ : "<=" |
| 35 | +GEQ : ">=" |
| 36 | +MINUS : "-" |
| 37 | +ASTERISK : "*" |
| 38 | +SLASH : "/" |
| 39 | +PERCENT : "%" |
| 40 | +DOUBLE_AMP : "&&" |
| 41 | +DOUBLE_PIPE : "||" |
| 42 | +PLUS : "+" |
| 43 | +NOT : "!" |
| 44 | +QMARK : "?" |
| 45 | + |
| 46 | +// Punctuation |
| 47 | +LPAR : "(" |
| 48 | +RPAR : ")" |
| 49 | +LBRACE : "{" |
| 50 | +RBRACE : "}" |
| 51 | +LSQB : "[" |
| 52 | +RSQB : "]" |
| 53 | +COMMA : "," |
| 54 | +DOT : "." |
| 55 | +EQ : /[ \t]*=(?!=|>)/ |
| 56 | +COLON : ":" |
| 57 | +DBLQUOTE : "\"" |
| 58 | + |
| 59 | +// Interpolation |
| 60 | +INTERP_START : "${" |
| 61 | + |
| 62 | +// Splat Operators |
| 63 | +ATTR_SPLAT : ".*" |
| 64 | +FULL_SPLAT_START : "[*]" |
| 65 | + |
| 66 | +// Special Operators |
| 67 | +FOR_OBJECT_ARROW : "=>" |
| 68 | +ELLIPSIS : "..." |
| 69 | +COLONS: "::" |
| 70 | + |
| 71 | +// Heredocs |
| 72 | +HEREDOC_TEMPLATE : /<<(?P<heredoc>[a-zA-Z][a-zA-Z0-9._-]+)\n?(?:.|\n)*?\n\s*(?P=heredoc)\n/ |
| 73 | +HEREDOC_TEMPLATE_TRIM : /<<-(?P<heredoc_trim>[a-zA-Z][a-zA-Z0-9._-]+)\n?(?:.|\n)*?\n\s*(?P=heredoc_trim)\n/ |
| 74 | + |
| 75 | +// Ignore whitespace (but not newlines, as they're significant in HCL) |
| 76 | +%ignore /[ \t]+/ |
| 77 | + |
| 78 | +// ============================================================================ |
| 79 | +// Rules |
| 80 | +// ============================================================================ |
| 81 | + |
| 82 | +// Top-level structure |
| 83 | +start : body |
| 84 | + |
| 85 | +// Body and basic constructs |
| 86 | +body : (new_line_or_comment? (attribute | block))* new_line_or_comment? |
| 87 | +attribute : identifier EQ expression |
| 88 | +block : identifier (identifier | string)* new_line_or_comment? LBRACE body RBRACE |
| 89 | + |
| 90 | +// Whitespace and comments |
| 91 | +new_line_or_comment: ( NL_OR_COMMENT )+ |
| 92 | + |
| 93 | +// Basic literals and identifiers |
| 94 | +identifier: IDENTIFIER |
| 95 | +int_lit: INT_LITERAL |
| 96 | +float_lit: FLOAT_LITERAL |
| 97 | +string: DBLQUOTE string_part* DBLQUOTE |
| 98 | +string_part: STRING_CHARS |
| 99 | + | ESCAPED_INTERPOLATION |
| 100 | + | interpolation |
| 101 | + |
| 102 | +// Expressions |
| 103 | +?expression : expr_term | operation | conditional |
| 104 | +interpolation: INTERP_START expression RBRACE |
| 105 | +conditional : expression QMARK new_line_or_comment? expression new_line_or_comment? COLON new_line_or_comment? expression |
| 106 | + |
| 107 | +// Operations |
| 108 | +?operation : unary_op | binary_op |
| 109 | +!unary_op : (MINUS | NOT) expr_term |
| 110 | +binary_op : expression binary_term new_line_or_comment? |
| 111 | +binary_term : binary_operator new_line_or_comment? expression |
| 112 | +!binary_operator : BINARY_OP |
| 113 | + |
| 114 | +// Expression terms |
| 115 | +expr_term : LPAR new_line_or_comment? expression new_line_or_comment? RPAR |
| 116 | + | float_lit |
| 117 | + | int_lit |
| 118 | + | string |
| 119 | + | tuple |
| 120 | + | object |
| 121 | + | function_call |
| 122 | + | index_expr_term |
| 123 | + | get_attr_expr_term |
| 124 | + | identifier |
| 125 | + | provider_function_call |
| 126 | + | heredoc_template |
| 127 | + | heredoc_template_trim |
| 128 | + | attr_splat_expr_term |
| 129 | + | full_splat_expr_term |
| 130 | + | for_tuple_expr |
| 131 | + | for_object_expr |
| 132 | + |
| 133 | +// Collections |
| 134 | +tuple : LSQB (new_line_or_comment* expression new_line_or_comment* COMMA)* (new_line_or_comment* expression)? new_line_or_comment* RSQB |
| 135 | +object : LBRACE new_line_or_comment? (new_line_or_comment* (object_elem | (object_elem COMMA)) new_line_or_comment*)* RBRACE |
| 136 | +object_elem : object_elem_key ( EQ | COLON ) expression |
| 137 | +object_elem_key : float_lit | int_lit | identifier | string | object_elem_key_dot_accessor | object_elem_key_expression |
| 138 | +object_elem_key_expression : LPAR expression RPAR |
| 139 | +object_elem_key_dot_accessor : identifier (DOT identifier)+ |
| 140 | + |
| 141 | +// Heredocs |
| 142 | +heredoc_template : HEREDOC_TEMPLATE |
| 143 | +heredoc_template_trim : HEREDOC_TEMPLATE_TRIM |
| 144 | + |
| 145 | +// Functions |
| 146 | +function_call : identifier LPAR new_line_or_comment? arguments? new_line_or_comment? RPAR |
| 147 | +arguments : (expression (new_line_or_comment* COMMA new_line_or_comment* expression)* (COMMA | ELLIPSIS)? new_line_or_comment*) |
| 148 | +provider_function_call: identifier COLONS identifier COLONS identifier LPAR new_line_or_comment? arguments? new_line_or_comment? RPAR |
| 149 | + |
| 150 | +// Indexing and attribute access |
| 151 | +index_expr_term : expr_term index |
| 152 | +get_attr_expr_term : expr_term get_attr |
| 153 | +attr_splat_expr_term : expr_term attr_splat |
| 154 | +full_splat_expr_term : expr_term full_splat |
| 155 | +?index : braces_index | short_index |
| 156 | +braces_index : LSQB new_line_or_comment? expression new_line_or_comment? RSQB |
| 157 | +short_index : DOT INT_LITERAL |
| 158 | +get_attr : DOT identifier |
| 159 | +attr_splat : ATTR_SPLAT get_attr* |
| 160 | +full_splat : FULL_SPLAT_START (get_attr | index)* |
| 161 | + |
| 162 | +// For expressions |
| 163 | +!for_tuple_expr : LSQB new_line_or_comment? for_intro new_line_or_comment? expression new_line_or_comment? for_cond? new_line_or_comment? RSQB |
| 164 | +!for_object_expr : LBRACE new_line_or_comment? for_intro new_line_or_comment? expression FOR_OBJECT_ARROW new_line_or_comment? expression new_line_or_comment? ELLIPSIS? new_line_or_comment? for_cond? new_line_or_comment? RBRACE |
| 165 | +!for_intro : FOR new_line_or_comment? identifier (COMMA identifier new_line_or_comment?)? new_line_or_comment? IN new_line_or_comment? expression new_line_or_comment? COLON new_line_or_comment? |
| 166 | +!for_cond : IF new_line_or_comment? expression |
0 commit comments