def try_read_rule(ctx: ReadContext) -> Optional[RuleExp]: loc0 = ctx.source.location name = try_read_name(ctx) if name is None: return None read_void(ctx) if ctx.source.pull(soft_assignment_mark): soft = True elif ctx.source.pull(hard_assignment_mark): soft = False else: raise ctx.source.error_expected_symbols(soft_assignment_mark, hard_assignment_mark) read_void(ctx) expression = read_expression(ctx) result = RuleExp(name, expression, soft) result.area = loc0.area(ctx.source.location) return result
def read_expression(ctx: ReadContext) -> Expression: loc0 = ctx.source.location alt_seq: List[List[Expression]] = [[]] while True: expression = try_read_expression_item(ctx) if expression is None: break alt_seq[-1].append(expression) read_void(ctx) if ctx.source.pull(alternation_mark): read_void(ctx) if len(alt_seq[-1]) == 0: raise ctx.error('Expected expression.') alt_seq.append([]) if len(alt_seq) == 0: raise ctx.error('Expected expression.') return generate_alt_seq_expression(alt_seq, ctx, loc0)
def parse_source(source: Source) -> List[Element]: ctx = ReadContext(source) elements = [] while True: read_void(ctx) rule = try_read_rule(ctx) if rule is None: break elements.append(rule) return elements
def try_read_optional(ctx: ReadContext) -> Optional[OptionalExp]: loc0 = ctx.source.location if not ctx.source.pull(optional_begin_mark): return None read_void(ctx) expression = read_expression(ctx) if not ctx.source.pull(optional_end_mark): raise ctx.source.error_expected_symbols(optional_end_mark) result = OptionalExp(expression) result.area = loc0.area(ctx.source.location) return result
def try_read_group(ctx: ReadContext) -> Optional[Expression]: loc0 = ctx.source.location if not ctx.source.pull(group_begin_mark): return None read_void(ctx) expression = read_expression(ctx) if not ctx.source.pull(group_end_mark): raise ctx.source.error_expected_symbols(group_end_mark) # override area expression.area = loc0.area(ctx.source.location) return expression
def try_read_reference(ctx: ReadContext) -> Optional[ReferenceExp]: loc0 = ctx.source.location name = try_read_name(ctx) if name is None: return None read_void(ctx) if (ctx.source.pull(soft_assignment_mark) or ctx.source.pull(hard_assignment_mark)): ctx.source.position = loc0.position return None result = ReferenceExp(name) result.area = loc0.area(ctx.source.location) return result
def try_read_negation(ctx: ReadContext) -> Optional[NegationExp]: loc0 = ctx.source.location if not ctx.source.pull(negation_mark): return None if read_void(ctx) > 0: raise ctx.source.error_expected_symbols(negation_mark) expression = try_read_expression_item(ctx) if expression is None: raise ctx.error('Expected expression.') result = NegationExp(expression) result.area = loc0.area(ctx.source.location) return result
def try_read_repetition(ctx: ReadContext) -> Optional[RepetitionExp]: loc0 = ctx.source.location if not ctx.source.pull(repetition_begin_mark): return None read_void(ctx) min_count = try_read_integer(ctx) max_count = None if min_count is not None: read_void(ctx) if ctx.source.pull(repetition_range_mark): read_void(ctx) max_count = try_read_integer(ctx) if max_count is None: raise ctx.error('Expected max_count.') read_void(ctx) elif ctx.source.pull(repetition_count_mark): max_count = min_count read_void(ctx) expression = read_expression(ctx) if ctx.source.pull(repetition_separator_mark): read_void(ctx) separator = read_expression(ctx) else: separator = None if not ctx.source.pull(repetition_end_mark): raise ctx.source.error_expected_symbols(repetition_end_mark) result = RepetitionExp(expression, separator, min_count, max_count) result.area = loc0.area(ctx.source.location) return result