Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
# 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",
location=source.previous_location,
)
else:
raise ParseError(
"Expected a value but this program is empty",
location=(0, 1),
)
def eat_next(self, *kinds):
if self.head is None:
if self.previous_location is None:
# Empty program
raise ParseError(
"Surprisingly, program was empty",
location=(0, 1),
)
end_of_last_location = self.previous_location[-1]
raise ParseError(
"Unexpected EOF, expected {kind}".format(
kind=', '.join(x.value for x in kinds),
),
location=(
end_of_last_location,
end_of_last_location + 1,
),
)
if self.head.kind in kinds:
old_head = self.head
self._advance()
return old_head
raise ParseError("Expected {kind}, got {actual_kind}".format(
kind=', '.join(x.value for x in kinds),
actual_kind=self.head.kind.value,
try:
adjective = tuple(source.eat_next(TokenKind.ATOM).value)
except ParseError:
# Must be a prepositional phrase
adjective = ()
prepositions = []
while source.match_next(TokenKind.PREPOSITION):
prepositions.append(source.head.value)
source.eat_next(TokenKind.PREPOSITION)
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),
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",
location=source.previous_location,
)
else:
raise ParseError(
"Expected a value but this program is empty",
location=(0, 1),
)
"""Entry point for debugging purposes."""
import sys
from routemaster.exit_conditions.parser import parse
from routemaster.exit_conditions.peephole import peephole_optimise
from routemaster.exit_conditions.exceptions import ParseError
from routemaster.exit_conditions.error_display import (
format_parse_error_message,
)
source = sys.stdin.read()
try:
for instruction, *args in peephole_optimise(parse(source)):
print(instruction.value, ', '.join(repr(x) for x in args))
except ParseError as e:
print(format_parse_error_message(
source=source,
error=e,
))
state, start = None, 0
for index, character in enumerate(src):
next_state = None
major_category = unicodedata.category(character) + character
for (from_state, category_match), to_state in STATE_MACHINE.items():
if (
from_state == state and
major_category.startswith(category_match)
):
next_state = to_state
break
if next_state is None:
raise ParseError(
"Unexpected '{0!r}'".format(character),
(index, index + 1),
)
if next_state != state:
if start != index:
assert state is not None
yield RawToken(
kind=state,
value=src[start:index],
location=(start, index),
)
start = index
state = next_state
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
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,
),
'>=': (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:
raise ParseError(
"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,
def __init__(self, source: str) -> None:
"""
Construct from source.
This will eagerly compile and report any errors.
"""
try:
self._instructions = tuple(parse(source))
except ParseError as exc:
raise ValueError(format_parse_error_message(
source=source,
error=exc,
)) from None
self._instructions = tuple(peephole_optimise(self._instructions))
self.source = source