2013-02-10 17 views
1

我創建了一個基於python的DSL只是爲了好玩。現在,它只是將文本編譯成直接執行python代碼的AST。我的意思是,如果我寫:自定義從基於Python的DSL中的異常追溯

a = int(read("input something: ")) 
b = a**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 

它:

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

每個節點將與類似下面的代碼被執行確實工作得很好。我想,當一些指令拋出異常時,異常堆棧回溯指向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中生成回溯?

回答

3

是的,但這樣做很醜。您可能需要look at how it's done in jinja2

Jinja是一個模板引擎。它處理回溯,以便它們指向模板錯誤。
也許你可以將它轉換爲你的代碼,以便它指向DSL錯誤。

+0

當然,它很醜,很醜。但從我目前看到的,沒有其他簡單的方法。感謝你的回答 :) – 2013-02-10 20:29:18