Bug 1041850 part 2 - Reuse the same re.Scanner instance when parsing different manifests. r=ted

Also cleanup the callbacks it uses.
This commit is contained in:
Mike Hommey 2014-07-25 07:07:19 +09:00
parent 92b736198b
commit 240a1f82b5

View File

@ -59,7 +59,7 @@ string = (basestring,)
# - rbp: right binding power
class ident_token(object):
def __init__(self, value):
def __init__(self, scanner, value):
self.value = value
def nud(self, parser):
# identifiers take their value from the value mappings passed
@ -67,7 +67,7 @@ class ident_token(object):
return parser.value(self.value)
class literal_token(object):
def __init__(self, value):
def __init__(self, scanner, value):
self.value = value
def nud(self, parser):
return self.value
@ -115,17 +115,17 @@ class end_token(object):
### derived literal tokens
class bool_token(literal_token):
def __init__(self, value):
def __init__(self, scanner, value):
value = {'true':True, 'false':False}[value]
literal_token.__init__(self, value)
literal_token.__init__(self, scanner, value)
class int_token(literal_token):
def __init__(self, value):
literal_token.__init__(self, int(value))
def __init__(self, scanner, value):
literal_token.__init__(self, scanner, int(value))
class string_token(literal_token):
def __init__(self, value):
literal_token.__init__(self, value[1:-1])
def __init__(self, scanner, value):
literal_token.__init__(self, scanner, value[1:-1])
precedence = [(end_token, rparen_token),
(or_op_token,),
@ -170,6 +170,9 @@ class ExpressionParser(object):
Identifiers take their values from the mapping provided.
"""
scanner = None
def __init__(self, text, valuemapping, strict=False):
"""
Initialize the parser
@ -186,35 +189,23 @@ class ExpressionParser(object):
"""
Lex the input text into tokens and yield them in sequence.
"""
# scanner callbacks
def bool_(scanner, t): return bool_token(t)
def identifier(scanner, t): return ident_token(t)
def integer(scanner, t): return int_token(t)
def eq(scanner, t): return eq_op_token()
def neq(scanner, t): return neq_op_token()
def or_(scanner, t): return or_op_token()
def and_(scanner, t): return and_op_token()
def lparen(scanner, t): return lparen_token()
def rparen(scanner, t): return rparen_token()
def string_(scanner, t): return string_token(t)
def not_(scanner, t): return not_op_token()
scanner = re.Scanner([
# Note: keep these in sync with the class docstring above.
(r"true|false", bool_),
(r"[a-zA-Z_]\w*", identifier),
(r"[0-9]+", integer),
(r'("[^"]*")|(\'[^\']*\')', string_),
(r"==", eq),
(r"!=", neq),
(r"\|\|", or_),
(r"!", not_),
(r"&&", and_),
(r"\(", lparen),
(r"\)", rparen),
(r"\s+", None), # skip whitespace
if not ExpressionParser.scanner:
ExpressionParser.scanner = re.Scanner([
# Note: keep these in sync with the class docstring above.
(r"true|false", bool_token),
(r"[a-zA-Z_]\w*", ident_token),
(r"[0-9]+", int_token),
(r'("[^"]*")|(\'[^\']*\')', string_token),
(r"==", eq_op_token()),
(r"!=", neq_op_token()),
(r"\|\|", or_op_token()),
(r"!", not_op_token()),
(r"&&", and_op_token()),
(r"\(", lparen_token()),
(r"\)", rparen_token()),
(r"\s+", None), # skip whitespace
])
tokens, remainder = scanner.scan(self.text)
tokens, remainder = ExpressionParser.scanner.scan(self.text)
for t in tokens:
yield t
yield end_token()