2020-04-26 23:10:26 +10:00
|
|
|
"""AST module."""
|
|
|
|
|
2020-04-28 03:27:07 +10:00
|
|
|
from enum import Enum
|
|
|
|
from typing import Union
|
2020-04-27 23:07:15 +10:00
|
|
|
from antlr4 import ParseTreeWalker
|
|
|
|
|
2020-04-28 12:00:06 +10:00
|
|
|
import jasminesnake.lex.JavaScriptParser as Parser
|
|
|
|
from . import nodes
|
2020-04-27 23:07:15 +10:00
|
|
|
from .parse_tree_listeners import ASTListener
|
|
|
|
|
|
|
|
JSP = Parser.JavaScriptParser
|
|
|
|
|
|
|
|
|
2020-04-28 12:00:06 +10:00
|
|
|
def from_parse_tree(tree: JSP.ProgramContext) -> nodes.Program:
|
2020-04-27 23:07:15 +10:00
|
|
|
"""Generate AST from ANTLR parse tree.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
tree (JSP.ProgramContext): ANTLR parse tree.
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
`Program` AST node, which is the root node.
|
|
|
|
"""
|
|
|
|
ast_listener = ASTListener()
|
|
|
|
ParseTreeWalker.DEFAULT.walk(ast_listener, tree)
|
|
|
|
return ast_listener.program_node
|
|
|
|
|
|
|
|
|
2020-04-28 03:27:07 +10:00
|
|
|
def to_ascii_tree(
|
2020-04-28 12:00:06 +10:00
|
|
|
node: Union[nodes.Position, nodes.SourceLocation, nodes.Node],
|
2020-04-28 03:27:07 +10:00
|
|
|
name_prefix: str = "",
|
|
|
|
nesting_lvl: int = 0,
|
|
|
|
):
|
|
|
|
if nesting_lvl < 0:
|
|
|
|
raise ValueError("Nesting level can't be below 0")
|
|
|
|
|
|
|
|
FORK = "+"
|
|
|
|
VERTICAL = "|"
|
|
|
|
HORIZONTAL = "-"
|
|
|
|
|
|
|
|
SUBENTRY_PREFIX = f"{FORK}{HORIZONTAL}{HORIZONTAL} "
|
|
|
|
NESTED_PREFIX = f"{VERTICAL} "
|
|
|
|
|
|
|
|
value = str(node)
|
|
|
|
children = None
|
|
|
|
|
|
|
|
if isinstance(node, Enum):
|
|
|
|
value = str(node.value)
|
|
|
|
|
|
|
|
if isinstance(node, list):
|
|
|
|
value = ""
|
|
|
|
children = [(index, val) for index, val in enumerate(node)]
|
|
|
|
|
|
|
|
if hasattr(node, "fields"):
|
|
|
|
children = [(k, node.fields[k]) for k in node.fields.keys()]
|
|
|
|
|
|
|
|
result = f"{NESTED_PREFIX * (nesting_lvl - 1)}{SUBENTRY_PREFIX * (nesting_lvl > 0)}"
|
|
|
|
result += f"{name_prefix}{value}\n"
|
|
|
|
|
|
|
|
if children is not None:
|
|
|
|
for (child_name, child_value) in children:
|
|
|
|
result += to_ascii_tree(child_value, f"{child_name}: ", nesting_lvl + 1)
|
|
|
|
|
|
|
|
# result += "\n"
|
|
|
|
|
|
|
|
return result
|
|
|
|
|
|
|
|
|
2020-04-27 23:07:15 +10:00
|
|
|
# Delete temporary imports
|
|
|
|
del JSP
|
|
|
|
del Parser
|