from lark import Lark

# =============================================================
# A ESTRUTURA DA PRECEDÊNCIA (HIERARQUIA)
# =============================================================
# Regra de ouro: O que você quer que seja resolvido PRIMEIRO 
# deve estar no nível mais BAIXO (mais longe do 'start').
# =============================================================

gramatica_matematica = """
    # O ponto de entrada tenta resolver uma 'expressao'
    ?start: expressao

    # NÍVEL 1: SOMA (Menor prioridade)
    # Uma expressão pode ser um termo sozinho OU uma soma.
    # O '?' antes do nome diz ao Lark: "Se não houver '+' aqui, 
    # não crie o nó 'expressao', passe direto para o 'termo'".
    ?expressao: termo
             | expressao "+" termo   -> soma

    # NÍVEL 2: MULTIPLICAÇÃO (Média prioridade)
    # Como 'expressao' chama 'termo', o computador é obrigado a 
    # entrar aqui para tentar entender o que é o 'termo'.
    ?termo: fator
          | termo "*" fator          -> multiplicacao

    # NÍVEL 3: FATOR (Maior prioridade / Base)
    # Aqui é onde estão os números ou o que está entre parênteses.
    # O parênteses força o computador a voltar para o topo (expressao).
    ?fator: NUMBER                   -> numero
          | "(" expressao ")"

    # Definições de Tokens
    %import common.NUMBER
    %import common.WS
    %ignore WS
"""

# Inicializamos o motor de análise
parser = Lark(gramatica_matematica)

# Exemplo: 2 + 3 * 4
# O Parser Top-Down lê o '2', vê o '+', mas antes de somar, 
# ele "desce" para ver se o que vem depois do '+' é algo 
# que 'manda' mais (como o '*' do 3 * 4).
try:
    print("--- ANÁLISE HIERÁRQUICA DE 2 + 3 * 4 ---")
    arvore = parser.parse("2 + 3 * 4")
    print(arvore.pretty())
except Exception as e:
    print(f"Erro na análise: {e}")