amplify-education / python-hcl2

MIT License
255 stars 56 forks source link

Two ternary operators - fail to parse #140

Open jeremycarroll opened 1 year ago

jeremycarroll commented 1 year ago

I had a parse error that I reduced to

resource "aws_instance" "jenkins_controller" {
  user_data = var.color == "blue" ? 0 :  1
  tags = {
    email          = var.assignee == "" ? null : var.assignee
    color          = var.color
  }
}

results in

Traceback (most recent call last):
  File "/Users/jcarroll/.local/share/virtualenvs/codeowners-dsyKmJWy/lib/python3.11/site-packages/lark/parsers/lalr_parser.py", line 126, in feed_token
    action, arg = states[state][token.type]
                  ~~~~~~~~~~~~~^^^^^^^^^^^^
KeyError: '__ANON_3'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "/Users/jcarroll/.local/share/virtualenvs/codeowners-dsyKmJWy/lib/python3.11/site-packages/hcl2/api.py", line 14, in load
    return loads(file.read(), with_meta=with_meta)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jcarroll/.local/share/virtualenvs/codeowners-dsyKmJWy/lib/python3.11/site-packages/hcl2/api.py", line 27, in loads
    tree = hcl2.parse(text + "\n")
           ^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jcarroll/.local/share/virtualenvs/codeowners-dsyKmJWy/lib/python3.11/site-packages/lark/lark.py", line 645, in parse
    return self.parser.parse(text, start=start, on_error=on_error)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jcarroll/.local/share/virtualenvs/codeowners-dsyKmJWy/lib/python3.11/site-packages/lark/parser_frontends.py", line 96, in parse
    return self.parser.parse(stream, chosen_start, **kw)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jcarroll/.local/share/virtualenvs/codeowners-dsyKmJWy/lib/python3.11/site-packages/lark/parsers/lalr_parser.py", line 41, in parse
    return self.parser.parse(lexer, start)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jcarroll/.local/share/virtualenvs/codeowners-dsyKmJWy/lib/python3.11/site-packages/lark/parsers/lalr_parser.py", line 171, in parse
    return self.parse_from_state(parser_state)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jcarroll/.local/share/virtualenvs/codeowners-dsyKmJWy/lib/python3.11/site-packages/lark/parsers/lalr_parser.py", line 193, in parse_from_state
    raise e
  File "/Users/jcarroll/.local/share/virtualenvs/codeowners-dsyKmJWy/lib/python3.11/site-packages/lark/parsers/lalr_parser.py", line 184, in parse_from_state
    state.feed_token(token)
  File "/Users/jcarroll/.local/share/virtualenvs/codeowners-dsyKmJWy/lib/python3.11/site-packages/lark/parsers/lalr_parser.py", line 129, in feed_token
    raise UnexpectedToken(token, expected, state=self, interactive_parser=None)
lark.exceptions.UnexpectedToken: Unexpected token Token('__ANON_3', 'color') at line 5, column 5.
Expected one of: 
    * SLASH
    * QMARK
    * __ANON_4
    * __ANON_0
    * STAR
    * MINUS
    * PLUS
    * COMMA
    * __ANON_8
    * __ANON_9
    * __ANON_5
    * __ANON_2
    * __ANON_7
    * PERCENT
    * MORETHAN
    * RBRACE
    * __ANON_6
    * LESSTHAN
    * __ANON_1

Python 3.11.3; HCL2: 4.3.2

IButskhrikidze commented 1 year ago

If you make parentheses for the entire ternary or for only a condition, it works. like those:

resource "aws_instance" "jenkins_controller" {
  user_data = var.color == "blue" ? 0 :  1
  tags = {
    email          = (var.assignee == "" ? null : var.assignee)
    color          = var.color
  }
}

or

resource "aws_instance" "jenkins_controller" {
  user_data = var.color == "blue" ? 0 :  1
  tags = {
    email          = (var.assignee == "") ? null : var.assignee
    color          = var.color
  }
}
jeremycarroll commented 1 year ago

@IButskhrikidze - I am trying to parse all the code in a repo, and it is what it is ... The parser is very close, but even one or two errors cause pain

gimbo commented 1 year ago

For me this bug appeared in 4.3.1; downgrading to 4.3.0 fixed it.

Garamotte commented 1 year ago

I have the same issue with 4.3.1 for a binary operation : priority = 20 + value.

When downgrading to 4.3.0, everything is OK.

dogmatic69 commented 1 year ago

also broken for multi-line ternary even if wrapped in ().

(var.foo ? 1 : 2) works

this does not

(
  var.foo
  ? 1
  : 2
)