Refactored to allow ConceptEvaluator

This commit is contained in:
2019-11-14 22:04:38 +01:00
parent 576ce77740
commit 9e10e77737
30 changed files with 2406 additions and 1007 deletions
+48 -9
View File
@@ -1,3 +1,4 @@
from core.builtin_concepts import BuiltinConcepts
from parsers.BaseParser import BaseParser, Node, ErrorNode
from dataclasses import dataclass
import ast
@@ -12,23 +13,50 @@ class PythonErrorNode(ErrorNode):
source: str
exception: Exception
def __post_init__(self):
log.debug("-> PythonErrorNode: " + str(self.exception))
# def __post_init__(self):
# log.debug("-> PythonErrorNode: " + str(self.exception))
@dataclass()
class PythonNode(Node):
source: str
ast: ast.AST
ast_: ast.AST
# def __repr__(self):
# return "PythonNode(source='" + self.source + "', ast=" + self.get_dump(self.ast_) + ")"
def __repr__(self):
return "PythonNode(" + ast.dump(self.ast) + ")"
# return "PythonNode(" + self.source + ")"
ast_type = "expr" if isinstance(self.ast_, ast.Expression) else "module"
return "PythonNode(" + ast_type + "='" + self.source + "')"
def __eq__(self, other):
if not isinstance(other, PythonNode):
return False
if self.source != other.source:
return False
self_dump = self.get_dump(self.ast_)
other_dump = self.get_dump(other.ast_)
return self_dump == other_dump
def __hash__(self):
return hash((self.source, self.ast_.hash))
@staticmethod
def get_dump(ast_):
dump = ast.dump(ast_)
for to_remove in [", ctx=Load()", ", kind=None", ", type_ignores=[]"]:
dump = dump.replace(to_remove, "")
return dump
class PythonParser(BaseParser):
"""
Parse Python scripts
"""
def __init__(self, source="<undef>"):
BaseParser.__init__(self, "PythonParser")
@@ -38,6 +66,8 @@ class PythonParser(BaseParser):
text = text if isinstance(text, str) else self.get_text_from_tokens(text)
text = text.strip()
sheerka = context.sheerka
# first, try to parse an expression
res, tree, error = self.try_parse_expression(text)
if not res:
@@ -47,10 +77,19 @@ class PythonParser(BaseParser):
self.has_error = True
error_node = PythonErrorNode(text, error)
self.error_sink.append(error_node)
return error_node
log.debug("Recognized python code.")
return PythonNode(text, tree)
ret = sheerka.ret(
self.name,
not self.has_error,
sheerka.new(
BuiltinConcepts.PARSER_RESULT,
parser=self,
source=text,
body=self.error_sink if self.has_error else PythonNode(text, tree),
try_parsed=None))
self.log_result(log, text, ret)
return ret
def try_parse_expression(self, text):
try:
@@ -91,6 +130,7 @@ class PythonGetNamesVisitor(ast.NodeVisitor):
"""
This visitor will find all the name declared in the ast
"""
def __init__(self):
self.names = set()
log.debug("Searching for names.")
@@ -98,4 +138,3 @@ class PythonGetNamesVisitor(ast.NodeVisitor):
def visit_Name(self, node):
log.debug(f"Found name : {node.id}")
self.names.add(node.id)