示例#1
0
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
示例#2
0
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)
示例#3
0
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
示例#4
0
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
示例#5
0
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
示例#6
0
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
示例#7
0
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
示例#8
0
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