我正在尝试使用pyparsing在Python中构建一个简单的lisp解释器。我已定义语言:
def parse(program):
_int = pp.Word(pp.nums).setParseAction(lambda s, l, t: [int(t[0])])
_float = pp.Combine(pp.Word(pp.nums) + '.' +
pp.Word(pp.nums)).setParseAction(lambda s, l, t: [float(t[0])])
number = _int ^ _float
extended_chars = "!$%&*+-./:<=>?@^_~"
symbol = pp.Word(pp.alphas + extended_chars, pp.alphanums + extended_chars)
atom = number ^ symbol
_list = pp.Forward()
_list << pp.nestedExpr(opener="(", closer=")", content=atom)
exp = atom ^ _list
return exp.parseString(program, parseAll=True).asList()
这主要是工作,但它解析:
parse('(1a)') => [[1, 'a']]
哪个应该被解释为无效语法。我假设这是因为解析器在nestedExpr
中的标记之间不需要空格。如何强制间距?
我不确定你真的想强迫空间,不应该'1 + 3'也有效吗?
而是通过添加asKeyword=True
关键字参数来修改Word表达式。
作为一个警告,nestedExpr
是一个非常简单的解析器,如果要解析嵌套表达式的内容,那么你应该使用递归解析器,或者可能使用infixNotation。在这个答案中看到更多:How do I implement this in ply, given how pyparsing works