Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
return
except ParseError:
pass
# Durations
try:
duration = source.eat_next(TokenKind.DURATION)
yield Operation.LITERAL, duration.value
return
except ParseError:
pass
# Numbers
try:
number = source.eat_next(TokenKind.NUMBER)
yield Operation.LITERAL, number.value
return
except ParseError:
pass
# No match
if source.head is not None:
raise ParseError(
"Expected a value, got {kind}".format(
kind=source.head.kind.value,
),
location=source.head.location,
)
else:
if source.previous_location is not None:
raise ParseError(
"Expected a value, but the EOF was reached",
yield from _parse_value(source)
if not adjective and not prepositions:
if source.head is not None:
raise ParseError(
"Expected an adjective or preposition",
source.head.location,
)
else:
raise ParseError(
"Expected an adjective or preposition afterwards, "
"but got the EOF",
source.previous_location,
)
yield Operation.PROPERTY, tuple(adjective), tuple(prepositions)
elif source.match_next(TokenKind.OPERATOR):
try:
operator, is_negative = {
'=': (Operation.EQ, False),
'/=': (Operation.EQ, True),
'<': (Operation.LT, False),
'>': (Operation.GT, False),
'<=': (Operation.GT, True),
'>=': (Operation.LT, True),
}[source.head.value]
except KeyError:
try:
suggested_replacement = \
OPERATOR_DID_YOU_MEAN[source.head.value]
raise ParseError(
else:
raise ParseError(
"Expected an adjective or preposition afterwards, "
"but got the EOF",
source.previous_location,
)
yield Operation.PROPERTY, tuple(adjective), tuple(prepositions)
elif source.match_next(TokenKind.OPERATOR):
try:
operator, is_negative = {
'=': (Operation.EQ, False),
'/=': (Operation.EQ, True),
'<': (Operation.LT, False),
'>': (Operation.GT, False),
'<=': (Operation.GT, True),
'>=': (Operation.LT, True),
}[source.head.value]
except KeyError:
try:
suggested_replacement = \
OPERATOR_DID_YOU_MEAN[source.head.value]
raise ParseError(
"Unknown operator {operator} "
"(did you mean {suggestion}?)".format(
operator=source.head.value,
suggestion=suggested_replacement,
),
location=source.head.location,
) from None
except KeyError:
"""Peephole evaluator optimiser."""
from routemaster.exit_conditions.operations import Operation
MATCHERS = [
(
[
(Operation.NOT,),
(Operation.NOT,),
],
[
],
),
(
[
(Operation.TO_BOOL,),
(Operation.TO_BOOL,),
],
[
(Operation.TO_BOOL,),
],
),
(
[
for preposition in reversed(prepositions):
prepositional_arguments[preposition.value] = stack.pop()
subject = stack.pop()
stack.append(
property_handler(property_name, subject, **prepositional_arguments),
)
EVALUATORS = {
Operation.TO_BOOL: _evaluate_to_bool,
Operation.AND: _evaluate_and,
Operation.OR: _evaluate_or,
Operation.NOT: _evaluate_not,
Operation.PROPERTY: _evaluate_property,
Operation.GT: _evaluate_gt,
Operation.LT: _evaluate_lt,
Operation.EQ: _evaluate_eq,
Operation.LITERAL: _evaluate_literal,
Operation.LOOKUP: _evaluate_lookup,
}
def evaluate(instructions, lookup, property_handler):
"""
Run the instructions given in `instructions`.
Returns the single result.
"""
stack = []
for instruction, *args in instructions:
EVALUATORS[instruction](stack, lookup, property_handler, *args)
return stack.pop()
def _parse_and_expr(source):
already_bool_converted = False
yield from _parse_or_expr(source)
while source.try_eat_next(TokenKind.AND):
if not already_bool_converted:
already_bool_converted = True
yield Operation.TO_BOOL,
yield from _parse_or_expr(source)
yield Operation.TO_BOOL,
yield Operation.AND,
[
(Operation.OR,),
],
),
(
[
(Operation.EQ,),
(Operation.TO_BOOL,),
],
[
(Operation.EQ,),
],
),
(
[
(Operation.LT,),
(Operation.TO_BOOL,),
],
[
(Operation.LT,),
],
),
(
[
(Operation.GT,),
(Operation.TO_BOOL,),
],
[
(Operation.GT,),
],
),
(
)
else:
raise ParseError(
"Expected an adjective or preposition afterwards, "
"but got the EOF",
source.previous_location,
)
yield Operation.PROPERTY, tuple(adjective), tuple(prepositions)
elif source.match_next(TokenKind.OPERATOR):
try:
operator, is_negative = {
'=': (Operation.EQ, False),
'/=': (Operation.EQ, True),
'<': (Operation.LT, False),
'>': (Operation.GT, False),
'<=': (Operation.GT, True),
'>=': (Operation.LT, True),
}[source.head.value]
except KeyError:
try:
suggested_replacement = \
OPERATOR_DID_YOU_MEAN[source.head.value]
raise ParseError(
"Unknown operator {operator} "
"(did you mean {suggestion}?)".format(
operator=source.head.value,
suggestion=suggested_replacement,
),
location=source.head.location,
) from None
def _parse_value(source):
# Immediate special-case: parentheticals
if source.try_eat_next(TokenKind.LEFT_PAREN):
yield from _parse_and_expr(source)
source.eat_next(TokenKind.RIGHT_PAREN)
return
# Atomic lookup
try:
atom = source.eat_next(TokenKind.ATOM)
yield Operation.LOOKUP, tuple(atom.value)
return
except ParseError:
pass
# Literals
try:
literal = source.eat_next(TokenKind.LITERAL)
yield Operation.LITERAL, literal.value
return
except ParseError:
pass
# Durations
try:
duration = source.eat_next(TokenKind.DURATION)
yield Operation.LITERAL, duration.value
"Unknown operator {operator}".format(
operator=source.head.value,
),
location=source.head.location,
) from None
if is_negative:
negated = not negated
source.eat_next(TokenKind.OPERATOR)
yield from _parse_value(source)
yield operator,
if negated:
yield Operation.TO_BOOL,
yield Operation.NOT,