Beispiel #1
0
def _rule_state_to_string(rule_state: RuleState,
                          grammar: Grammar) -> Tuple[str, str, str]:
    rule = grammar.rule_at(rule_state.rule_index)
    key = rule.key
    processed_str = ' '.join(rule.symbols[:rule_state.num_processed])
    unprocessed_str = ' '.join(rule.symbols[rule_state.num_processed:])
    lookaheads_str = ' '.join(
        [str(symbol) for symbol in rule_state.lookaheads])
    return f'{key}', f'{processed_str}⬤{unprocessed_str}', f'{lookaheads_str}'
Beispiel #2
0
def parse(tokens: List[Node], grammar: Grammar, table: ParseTable) -> Node:
    from cmaj.parser.table import Action
    assert table.num_rows > 0
    stack: Stack = []
    row = 0
    tokens = tokens + [Node(Grammar.AUGMENTED_EOF)]
    token_index = 0
    while True:
        token = tokens[token_index]
        action = table.action(row, token.key)
        if action is None:
            raise ParserError(f'Unexpected token: {tokens[token_index]!r}')
        elif action.key == Action.ACCEPT:
            break
        elif action.key == Action.SHIFT:
            stack.append((row, tokens[token_index]))
            row = action.index
            token_index += 1
        elif action.key == Action.GOTO:
            row = action.index
        elif action.key == Action.REDUCE:
            rule_index = action.index
            rule = grammar.rule_at(rule_index)

            stack, row, nodes = _reduce_stack(stack, rule)
            node = _reduce_nodes(nodes, rule)
            stack.append((row, node))

            action = table.action(row, node.key)
            assert action.key == Action.GOTO
            row = action.index
        else:
            raise ParserError(f'Unexpected parser action {action!r} for token: {tokens[token_index]!r}')

    if len(stack) != 1:
        raise ParserError(f'Found unprocessed tokens: {_to_symbols(stack)!r}')
    return stack[0][1]
Beispiel #3
0
 def __init__(self, state: RuleState, grammar: Grammar) -> None:
     rule = grammar.rule_at(state.rule_index)
     self._key = rule.key
     self._unprocessed_symbols = rule.symbols[state.num_processed:]