1

我创建一个基于 python 的 DSL 只是为了好玩。现在,它只是将文本编译成直接执行 python 代码的 AST。我的意思是,如果我写:

a = int(read("input something: "))
b = a**2

它将其转换为一棵树,例如:

Program:
  VariableSet a:
    Call:
      VariableGet int
      Call:
        VariableGet read
        Literal("input something: ")
  VariableSet b:
    BinaryExpession **:
       VariableGet a
       Literal(2)

这些节点中的每一个都将使用如下代码执行:

class VariableSet(object):
    def __init__(self, name, expr):
        self.name = name
        self.expr = expr

    def __call__(self, scope):
        value = self.expr(scope)
        scope.put(self.name, value)
        return value

它工作得很好。我希望,当某些指令引发异常时,异常堆栈回溯指向 DSL 源代码,而不是 python AST 代码。现在,我看到的只有:

Traceback (most recent call last):
  File "parser.py", line 164, in <module>
    parse(data)(scope)  
  File "/home/juanplopes/Projects/my-parser/ast.py", line 158, in __call__
    result = expr(scope)
  File "/home/juanplopes/Projects/my-parser/ast.py", line 63, in __call__
    value = self.expr(scope)
  File "/home/juanplopes/Projects/my-parser/ast.py", line 81, in __call__
    return self.method(scope)(*[arg(scope) for arg in self.args])
  File "/home/juanplopes/Projects/my-parser/ast.py", line 81, in __call__
    return self.method(scope)(*[arg(scope) for arg in self.args])
  File "parser.py", line 153, in read
    raise Exception('some exception')
Exception: some exception

有没有办法自定义如何在 python 中生成回溯?

4

1 回答 1

3

是的,但这样做很丑陋。

您可能想看看它是如何在jinja2.

Jinja 是一个模板引擎。它处理回溯,以便它们指向模板错误。
也许您可以将其转换为您的代码,以便它指向 DSL 错误。

于 2013-02-10T19:46:17.983 回答