我在继承定义时努力工作setParseAction
(我不知道如何用英语表达,所以举个例子):
from __future__ import division
from decimal import Decimal
from pyparsing import Word, alphas, ParseException, Literal, CaselessLiteral \
, Combine, Optional, nums, Or, Forward, ZeroOrMore, StringEnd, alphanums, Suppress \
, sglQuotedString, dblQuotedString, Group \
, restOfLine, Regex, stringEnd
class ASTNode(object):
def __init__(self, tokens):
self.tokens = tokens
self.assignFields()
def __str__(self):
return self.__class__.__name__ + ':' + str(self.__dict__)
__repr__ = __str__
class ConstantNode(ASTNode):
def assignFields(self):
#print " ", self.tokens
self.setValue(self.tokens[0])
def transform(self, value):
return value
def setValue(self, value):
self.constant = self.transform(value)
del self.tokens
class StringNode(ConstantNode):
pass
class BoolNode(ConstantNode):
def transform(self, value):
return bool(value)
class IntNode(ConstantNode):
def transform(self, value):
return int(value)
class FloatNode(ConstantNode):
def transform(self, value):
print value
return Decimal(value)
class AssignmentNode(ASTNode):
def assignFields(self):
#print self.tokens
self.lhs, self.rhs = self.tokens
del self.tokens
LPAR, RPAR, LBRACK, RBRACK, LBRACE, RBRACE, SEMI, COMMA = map(Suppress, "()[]{};,")
PLUS = Literal("+")
MINUS = Literal("-")
MULT = Literal("*")
DIV = Literal("/")
ASSIGN = Literal("=")
POINT = Literal('.')
TRUE = Literal('True')
FALSE = Literal('False')
SEP = Literal(':').suppress()
NAME = Word(alphas + '_?', alphanums + '_?')
TYPE = SEP + NAME
COMMENT = "#" + restOfLine
BOOLEANS = TRUE | FALSE
BOOLEANS.setParseAction(BoolNode)
EXPR = Forward()
ADDOP = PLUS | MINUS
MULTOP = MULT | DIV
PLUSORMINUS = PLUS | MINUS
#Strings
STR = dblQuotedString.setParseAction(ConstantNode) | sglQuotedString.setParseAction(ConstantNode)
STRINGS = STR
#Numbers
NUMBER = Word(nums)
INTEGER = Combine(Optional(PLUSORMINUS) + NUMBER)
FLOATNUMBER = Combine(INTEGER.copy() +
Optional(POINT + Optional(NUMBER)) +
Optional(INTEGER.copy())
)
MONEY = Combine(FLOATNUMBER.copy() + Word("$").suppress())
TYPED_FLOATNUMBER = Combine(FLOATNUMBER + Word(alphas))
INTEGER.setParseAction(IntNode)
FLOATNUMBER.setParseAction(FloatNode)
NUMBERS = MONEY | TYPED_FLOATNUMBER | FLOATNUMBER
TEST_GRAMMAR = """
#Single values
True
False
1 #Int32
1.0 #Float
1$ #MONEY
25.3mt #Typed number"""
一切都解析,但不调用布尔和整数节点,只调用浮点数。
['True']
['False']
1
[FloatNode:{'constant': Decimal('1')}]
1.0
[FloatNode:{'constant': Decimal('1.0')}]
['1']
['25.3mt']
[ConstantNode:{'constant': "'hello world'"}]
[ConstantNode:{'constant': '"hello world"'}]
['2002-08-10']
['100000']
['2002-08-10-100000']
1
[AssignmentNode:{'rhs': FloatNode:{'constant': Decimal('1')}, 'lhs': 'x'}]
1.0
[AssignmentNode:{'rhs': FloatNode:{'constant': Decimal('1.0')}, 'lhs': 'x'}]
[AssignmentNode:{'rhs': '1', 'lhs': 'x'}]
[AssignmentNode:{'rhs': '12.2mt', 'lhs': 'x'}]
我知道 setParseAction 与部分语法的定义有关。但是,我发现如果 chain 之类FLOATNUMBER
的因为是基于INTEGER
.