def __str__(self):
raise NotImplementerError
+ def __repr__(self):
+ return str(self)
+
class WildcardMatcher(ValueMatcher):
class ApproxValueMatcher(ValueMatcher):
-
def __init__(self, refValue, tolerance = 2**-23):
self.refValue = refValue
self.tolerance = tolerance
return ''.join(['%s\n' % refCall for refCall in self.refCalls])
+#######################################################################
+
EOF = -1
SKIP = -2
return token
-ID = 0
-NUMBER = 1
-HEXNUM = 2
-STRING = 3
+#######################################################################
-LPAREN = 4
-RPAREN = 5
-LCURLY = 6
-RCURLY = 7
-COMMA = 8
-AMP = 9
-EQUAL = 11
-
-BLOB = 12
+ID, NUMBER, HEXNUM, STRING, PRAGMA, LPAREN, RPAREN, LCURLY, RCURLY, COMMA, AMP, EQUAL, BLOB = xrange(13)
class CallScanner(Scanner):
# String IDs
(STRING, r'"[^"\\]*(?:\\.[^"\\]*)*"', False),
+
+ # Pragma
+ (PRAGMA, r'#[^\r\n]*', False),
]
# symbol table
lexer = CallLexer(fp = stream)
Parser.__init__(self, lexer)
+ def eof(self):
+ return self.match(EOF)
+
def parse(self):
- while not self.match(EOF):
+ while not self.eof():
+ self.parse_element()
+
+ def parse_element(self):
+ if self.lookahead.type == PRAGMA:
+ # TODO
+ token = self.consume()
+ self.handlePragma(token.text)
+ else:
self.parse_call()
def parse_call(self):
+ while self.lookahead.type == PRAGMA:
+ # TODO
+ token = self.consume()
+ print token.text
+
if self.lookahead.type == NUMBER:
token = self.consume()
callNo = int(token.text)
else:
ret = None
- self.handle_call(callNo, functionName, args, ret)
+ return self.handleCall(callNo, functionName, args, ret)
def parse_pair(self):
'''Parse a `name = value` pair.'''
if self.match(AMP):
self.consume()
value = [self.parse_value()]
- return ArrayMatcher(value)
+ return self.handleArray(value)
elif self.match(ID):
token = self.consume()
value = token.text
- return LiteralValueMatcher(value)
+ return self.handleID(value)
elif self.match(STRING):
token = self.consume()
value = token.text
- return LiteralValueMatcher(value)
+ return self.handleString(value)
elif self.match(NUMBER):
token = self.consume()
value = float(token.text)
- return ApproxValueMatcher(value)
+ return self.handleFloat(value)
elif self.match(HEXNUM):
token = self.consume()
value = int(token.text, 16)
- return LiteralValueMatcher(value)
+ return self.handleInt(value)
elif self.match(LCURLY):
value = self.parse_sequence(LCURLY, RCURLY, self.parse_opt_pair)
if len(value) and isinstance(value[0], tuple):
- return StructMatcher(dict(value))
+ value = dict(value)
+ return self.handleStruct(value)
else:
- return ArrayMatcher(value)
+ return self.handleArray(value)
elif self.match(BLOB):
token = self.consume()
self.consume(LPAREN)
length = self.consume()
self.consume(RPAREN)
- # TODO
- return WildcardMatcher()
+ return self.handleBlob()
else:
self.error()
self.consume(rtype)
return elements
+
+ def handleID(self, value):
+ return LiteralValueMatcher(value)
+
+ def handleInt(self, value):
+ return LiteralValueMatcher(value)
+
+ def handleFloat(self, value):
+ return ApproxValueMatcher(value)
+
+ def handleString(self, value):
+ return LiteralValueMatcher(value)
- def handle_call(self, callNo, functionName, args, ret):
+ def handleArray(self, value):
+ return ArrayMatcher(value)
+
+ def handleStruct(self, value):
+ return StructMatcher(value)
+
+ def handleBlob(self, value):
+ # TODO
+ return WildcardMatcher()
+
+ def handleCall(self, callNo, functionName, args, ret):
matcher = CallMatcher(functionName, args, ret)
if callNo is not None:
sys.stdout.write(str(matcher))
sys.stdout.write('\n')
+ def handlePragma(self, line):
+ sys.stdout.write(line)
+ sys.stdout.write('\n')
+
def main():
parser = CallParser(sys.stdin)