|
1 | 1 | """A parser for HCL2 implemented using the Lark parser""" |
2 | 2 | from pathlib import Path |
3 | 3 |
|
4 | | -from hcl2.transformer import DictTransformer |
5 | | - |
6 | | -THIS_DIR = Path(__file__).absolute().resolve().parent |
7 | | -PARSER_FILE = THIS_DIR / "lark_parser.py" |
8 | | - |
| 4 | +from lark import Lark |
9 | 5 |
|
10 | | -def create_parser_file(parser_file: Path = PARSER_FILE) -> None: |
11 | | - """ |
12 | | - Parsing the Lark grammar takes about 0.5 seconds. In order to improve performance we can cache the parser |
13 | | - file. The below code caches the entire python file which is generated by Lark's standalone parser feature |
14 | | - See: https://github.com/lark-parser/lark/blob/master/lark/tools/standalone.py |
15 | | -
|
16 | | - Lark also supports serializing the parser config but the deserialize function did not work for me. |
17 | | - The lark state contains dicts with numbers as keys which is not supported by json so the serialized |
18 | | - state can't be written to a json file. Exporting to other file types would have required |
19 | | - adding additional dependencies or writing a lot more code. Lark's standalone parser |
20 | | - feature works great but it expects to be run as a separate shell command |
21 | | - The below code copies some of the standalone parser generator code in a way that we can use |
22 | | - """ |
23 | | - # This function is needed only if standalone parser is not yet compiled. |
24 | | - # pylint: disable=import-outside-toplevel |
25 | | - from lark import Lark |
26 | | - from lark.tools.standalone import gen_standalone |
27 | | - |
28 | | - lark_file = THIS_DIR / "hcl2.lark" |
29 | | - with open(parser_file, "w", encoding="utf-8") as parser_file_stream: |
30 | | - lark_inst = Lark(lark_file.read_text(), parser="lalr", lexer="contextual") |
31 | | - parser_file_stream.write("# mypy: ignore-errors\n") |
32 | | - gen_standalone(lark_inst, out=parser_file_stream) |
| 6 | +from hcl2.transformer import DictTransformer |
33 | 7 |
|
34 | 8 |
|
35 | | -if not PARSER_FILE.exists(): |
36 | | - create_parser_file(PARSER_FILE) |
| 9 | +PARSER_FILE = Path(__file__).absolute().resolve().parent / ".lark_cache.bin" |
37 | 10 |
|
38 | | -# pylint: disable=wrong-import-position |
39 | | -# Lark_StandAlone needs to be imported after the above block of code because lark_parser.py might not exist |
40 | | -from hcl2.lark_parser import Lark_StandAlone |
41 | 11 |
|
42 | | -hcl2 = Lark_StandAlone(transformer=DictTransformer()) |
| 12 | +hcl2 = Lark.open( |
| 13 | + "hcl2.lark", |
| 14 | + parser="lalr", |
| 15 | + cache=str(PARSER_FILE), # Disable/Delete file to effect changes to the grammar |
| 16 | + rel_to=__file__, |
| 17 | + transformer=DictTransformer(), |
| 18 | +) |
0 commit comments