Sapien IA
Matemática Dissertativa

corrige os erros existentes nestes ficheiros, para que seja gerada uma árvore sintática abstrata: mocp_tester.py from antlr4 import * from antlr4.tree.Tree import TerminalNode import sys import MocpLexer from MocpParser import MocpParser from mocpvisitor import MocpAstBuilder, printast from antlr4.error.ErrorListener import ErrorListener ========================= ERROS ========================= class MocpErrorListener(ErrorListener): def syntaxError(self, recognizer, offendingSymbol, line, column, msg, e): print(f"Erro sintático linha {line}, coluna {column}: {msg}") ========================= PARSE TREE ========================= def printparsetree(node, parser, indent=0): prefix = " " * indent if isinstance(node, TerminalNode): print(prefix + node.getText()) return if hasattr(node, "getRuleIndex"): print(prefix + parser.ruleNames[node.getRuleIndex()]) for i in range(node.getChildCount()): printparsetree(node.getChild(i), parser, indent + 2) ========================= MAIN ========================= def main(file): input_stream = FileStream(file, encoding="utf-8") lexer = MocpLexer.MocpLexer(input_stream) tokens = CommonTokenStream(lexer) parser = MocpParser(tokens) parser.removeErrorListeners() # Remove default error listeners parser.addErrorListener(MocpErrorListener()) # Add custom error listener tree = parser.program() print("\n================ PARSE TREE ================\n") printparsetree(tree, parser) print("\n================ AST ================\n") ast = MocpAstBuilder().visit(tree) print_ast(ast) if name == "main": if len(sys.argv) < 2: print("Uso: python mocptester.py <caminhodo_arquivo>") else: main(sys.argv[1]) mocp_visitor.py from antlr4 import * from MocpParserVisitor import MocpParserVisitor ========================================================= AST NODES ========================================================= class Node: def init(self, tipo): self.tipo = tipo self.filhos = [] class Program(Node): def init(self): super().init("Program") self.funcoes = [] self.variaveis = [] class Function(Node): def init(self, nome, retorno): super().init("Function") self.nome = nome self.retorno = retorno self.corpo = None class Id(Node): def init(self, name): super().init("Id") self.name = name class Lit(Node): def init(self, value): super().init("Lit") self.value = value class BinOp(Node): def init(self, op, left, right): super().init(f"Bin({op})") self.op = op self.left = left self.right = right class Return(Node): def init(self): super().init("Return") self.valor = None ========================================================= VISITOR ========================================================= class MocpAstBuilder(MocpParserVisitor): def visitProgram(self, ctx): p = Program() funcs = ctx.declaracaoFuncao() or [] vars_ = ctx.declaracaoVariavel() or [] for f in funcs: if f is not None: p.funcoes.append(self.visit(f)) for v in vars_: if v is not None: p.variaveis.append(self.visit(v)) return p def visitDeclaracaoFuncao(self, ctx): nome = ctx.ID().getText() if ctx.ID() else "main" retorno = ctx.tipo().getText() if ctx.tipo() else "void" f = Function(nome, retorno) if ctx.block(): f.corpo = self.visit(ctx.block()) return f def visitBlock(self, ctx): node = Node("Block") instrs = ctx.instrucao() or [] for instr in instrs: if instr is not None: node.filhos.append(self.visit(instr)) return node def visitInstrucao(self, ctx): atr = ctx.atribuicao() if atr: if isinstance(atr, list) and len(atr) == 0: return Node("EmptyAssign") return self.visit(atr) if ctx.RETORNAR(): r = Return() expr = ctx.expr() if expr: val = self.visit(expr) r.valor = val r.filhos.append(val) return r expr = ctx.expr() if expr: return self.visit(expr) return Node("Instrucao") def visitAtribuicao(self, ctx): node = Node("Assign") if ctx.ID(): node.filhos.append(Id(ctx.ID().getText())) if ctx.expr(): node.filhos.append(self.visit(ctx.expr())) return node def visitExpr(self, ctx): if ctx is None: return Node("EmptyExpr") Check for numeric literals and strings

corrige os erros existentes nestes ficheiros, para que seja gerada uma árvore sintática abstrata:
mocp_tester.py
from antlr4 import *
from antlr4.tree.Tree import TerminalNode
import sys
import MocpLexer
from MocpParser import MocpParser
from mocpvisitor import MocpAstBuilder, printast
from antlr4.error.ErrorListener import ErrorListener

=========================

ERROS

=========================

class MocpErrorListener(ErrorListener):
def syntaxError(self, recognizer, offendingSymbol, line, column, msg, e):
print(f"Erro sintático linha {line}, coluna {column}: {msg}")

=========================

PARSE TREE

=========================

def printparsetree(node, parser, indent=0):
prefix = " " * indent

if isinstance(node, TerminalNode):
print(prefix + node.getText())
return

if hasattr(node, "getRuleIndex"):
print(prefix + parser.ruleNames[node.getRuleIndex()])
for i in range(node.getChildCount()):
printparsetree(node.getChild(i), parser, indent + 2)

=========================

MAIN

=========================

def main(file):
input_stream = FileStream(file, encoding="utf-8")

lexer = MocpLexer.MocpLexer(input_stream)
tokens = CommonTokenStream(lexer)
parser = MocpParser(tokens)

parser.removeErrorListeners() # Remove default error listeners
parser.addErrorListener(MocpErrorListener()) # Add custom error listener

tree = parser.program()

print("\n================ PARSE TREE ================\n")
printparsetree(tree, parser)

print("\n================ AST ================\n")
ast = MocpAstBuilder().visit(tree)
print_ast(ast)

if name == "main":
if len(sys.argv) < 2:
print("Uso: python mocptester.py <caminhodo_arquivo>")
else:
main(sys.argv[1])
mocp_visitor.py
from antlr4 import *
from MocpParserVisitor import MocpParserVisitor

=========================================================

AST NODES

=========================================================

class Node:
def init(self, tipo):
self.tipo = tipo
self.filhos = []

class Program(Node):
def init(self):
super().init("Program")
self.funcoes = []
self.variaveis = []

class Function(Node):
def init(self, nome, retorno):
super().init("Function")
self.nome = nome
self.retorno = retorno
self.corpo = None

class Id(Node):
def init(self, name):
super().init("Id")
self.name = name

class Lit(Node):
def init(self, value):
super().init("Lit")
self.value = value

class BinOp(Node):
def init(self, op, left, right):
super().init(f"Bin({op})")
self.op = op
self.left = left
self.right = right

class Return(Node):
def init(self):
super().init("Return")
self.valor = None

=========================================================

VISITOR

=========================================================

class MocpAstBuilder(MocpParserVisitor):
def visitProgram(self, ctx):
p = Program()

funcs = ctx.declaracaoFuncao() or []
vars_ = ctx.declaracaoVariavel() or []

for f in funcs:
if f is not None:
p.funcoes.append(self.visit(f))

for v in vars_:
if v is not None:
p.variaveis.append(self.visit(v))

return p

def visitDeclaracaoFuncao(self, ctx):
nome = ctx.ID().getText() if ctx.ID() else "main"
retorno = ctx.tipo().getText() if ctx.tipo() else "void"

f = Function(nome, retorno)

if ctx.block():
f.corpo = self.visit(ctx.block())

return f

def visitBlock(self, ctx):
node = Node("Block")
instrs = ctx.instrucao() or []

for instr in instrs:
if instr is not None:
node.filhos.append(self.visit(instr))

return node

def visitInstrucao(self, ctx):
atr = ctx.atribuicao()

if atr:
if isinstance(atr, list) and len(atr) == 0:
return Node("EmptyAssign")
return self.visit(atr)

if ctx.RETORNAR():
r = Return()
expr = ctx.expr()
if expr:
val = self.visit(expr)
r.valor = val
r.filhos.append(val)

return r

expr = ctx.expr()
if expr:
return self.visit(expr)

return Node("Instrucao")

def visitAtribuicao(self, ctx):
node = Node("Assign")

if ctx.ID():
node.filhos.append(Id(ctx.ID().getText()))

if ctx.expr():
node.filhos.append(self.visit(ctx.expr()))

return node

def visitExpr(self, ctx):
if ctx is None:
return Node("EmptyExpr")

Check for numeric literals and strings

Resolução completa

Explicação passo a passo

Resumo da resposta

Correção de Erros nos Ficheiros Mocp

Esta tarefa envolve revisão de código Python com ANTLR4, não uma questão matemática tradicional. Vou identificar e corrigir os erros estruturais em ambos os ficheiros.


Análise dos Problemas Identificados

FicheiroTipo de ErroDescrição
mocp_tester.pyImportaçãoFaltam verificações de erro no parser
mocp_visitor.pyCódigo IncompletoMétodos visit não implementados
mocp_visitor.pyLógicaCondições mal estruturadas
mocp_visitor.pySintaxeCódigo cortado abruptamente

## Correção do Ficheiro mocp_tester.py

Problema Principal

O parser pode falhar silenciosamente sem tratamento adequado de exceções.

def main(file):
    input_stream = FileStream(file, encoding="utf-8")

    lexer = MocpLexer.MocpLexer(input_stream)
    tokens = CommonTokenStream(lexer)
    parser = MocpParser(tokens)

    parser.removeErrorListeners()
    parser.addErrorListener(MocpErrorListener())

    # CORREÇÃO: Verificar se há erros antes de gerar o AST
    tree = parser.program()
    
    if parser.getNumberOfSyntaxErrors() > 0:
        print("ERRO: Não foi possível gerar AST devido a erros sintáticos")
        return None

    print("\n================ PARSE TREE ================\n")
    print_parse_tree(tree, parser)

    print("\n================ AST ================\n")
    ast = MocpAstBuilder().visit(tree)
    print_ast(ast)
    
    return ast

## Correção Completa do Ficheiro mocp_visitor.py

Problema Principal

O método visitExpr está incompleto e faltam implementações para operações binárias.

from antlr4 import *
from MocpParserVisitor import MocpParserVisitor

# =========================================================
# AST NODES
# =========================================================
class Node:
    def __init__(self, tipo):
        self.tipo = tipo
        self.filhos = []


class Program(Node):
    def __init__(self):
        super().__init__("Program")
        self.funcoes = []
        self.variaveis = []


class Function(Node):
    def __init__(self, nome, retorno):
        super().__init__("Function")
        self.nome = nome
        self.retorno = retorno
        self.corpo = None


class Id(Node):
    def __init__(self, name):
        super().__init__("Id")
        self.name = name


class Lit(Node):
    def __init__(self, value):
        super().__init__("Lit")
        self.value = value


class BinOp(Node):
    def __init__(self, op, left, right):
        super().__init__(f"Bin({op})")
        self.op = op
        self.left = left
        self.right = right


class Return(Node):
    def __init__(self):
        super().__init__("Return")
        self.valor = None


# =========================================================
# VISITOR
# =========================================================
class MocpAstBuilder(MocpParserVisitor):
    def visitProgram(self, ctx):
        p = Program()
        
        funcs = ctx.declaracaoFuncao() if hasattr(ctx, 'declaracaoFuncao') else []
        vars_ = ctx.declaracaoVariavel() if hasattr(ctx, 'declaracaoVariavel') else []
        
        funcs = funcs or []
        vars_ = vars_ or []
        
        for f in funcs:
            if f is not None:
                p.funcoes.append(self.visit(f))
        
        for v in vars_:
            if v is not None:
                p.variaveis.append(self.visit(v))
        
        return p
    
    def visitDeclaracaoFuncao(self, ctx):
        nome = ctx.ID().getText() if ctx.ID() else "main"
        retorno = ctx.tipo().getText() if ctx.tipo() else "void"
        
        f = Function(nome, retorno)
        
        if ctx.block():
            f.corpo = self.visit(ctx.block())
        
        return f
    
    def visitBlock(self, ctx):
        node = Node("Block")
        instrs = ctx.instrucao() if hasattr(ctx, 'instrucao') else []
        instrs = instrs or []
        
        for instr in instrs:
            if instr is not None:
                node.filhos.append(self.visit(instr))
        
        return node
    
    def visitInstrucao(self, ctx):
        atr = ctx.atribuicao()
        
        if atr:
            if isinstance(atr, list) and len(atr) == 0:
                return Node("EmptyAssign")
            return self.visit(atr)
        
        if ctx.RETORNAR():
            r = Return()
            expr = ctx.expr()
            if expr:
                val = self.visit(expr)
                r.valor = val
                r.filhos.append(val)
            
            return r
        
        expr = ctx.expr()
        if expr:
            return self.visit(expr)
        
        return Node("Instrucao")
    
    def visitAtribuicao(self, ctx):
        node = Node("Assign")
        
        if ctx.ID():
            node.filhos.append(Id(ctx.ID().getText()))
        
        if ctx.expr():
            node.filhos.append(self.visit(ctx.expr()))
        
        return node
    
    def visitExpr(self, ctx):
        if ctx is None:
            return Node("EmptyExpr")
        
        # VERIFICAÇÃO DE NUMERIC LITERALS
        if ctx.NUMERO():
            valor = float(ctx.NUMERO().getText())
            return Lit(valor)
        
        # VERIFICAÇÃO DE STRINGS
        if ctx.STRING():
            valor = ctx.STRING().getText()
            return Lit(valor)
        
        # VERIFICAÇÃO DE IDENTIFICADORES
        if ctx.ID():
            return Id(ctx.ID().getText())
        
        # OPERAÇÕES BINÁRIAS (CORREÇÃO CRÍTICA)
        if ctx.binExpr():
            left = self.visit(ctx.binExpr().expr(0))
            op_text = ctx.binExpr().binOp().getText()
            right = self.visit(ctx.binExpr().expr(1))
            return BinOp(op_text, left, right)
        
        # OPERAÇÕES UNÁRIAS
        if ctx.unExpr():
            op_text = ctx.unExpr().unOp().getText()
            operand = self.visit(ctx.unExpr().expr())
            return BinOp(op_text, operand, None)
        
        return Node("Expr")
    
    # MÉTODOS ADICIONAIS NECESSÁRIOS
    def visitTipo(self, ctx):
        return ctx.getText()
    
    def defaultResult(self):
        return None
    
    def aggregateResult(self, aggregate, nextResult):
        if nextResult is None:
            return aggregate
        elif aggregate is None:
            return nextResult
        else:
            if isinstance(aggregate, list):
                aggregate.append(nextResult)
                return aggregate
            return [aggregate, nextResult]

## Resumo das Correções Aplicadas

  1. Tratamento de erros no parser → Adicionado verificação de getNumberOfSyntaxErrors()
  2. Método visitExpr completo → Implementada lógica para números, strings, IDs e operações
  3. Verificação de atributos → Uso de hasattr() para evitar AttributeError
  4. Métodos auxiliares → Adicionados defaultResult() e aggregateResult() obrigatórios no Visitor Pattern
  5. Operações binárias/unárias → Implementação correta da recursão no AST

## Teste Recomendado

Após as correções, execute:

python mocp_tester.py <arquivo.mocp>

Verifique se:

  • ✅ A árvore sintática é gerada sem erros
  • ✅ O AST contém todos os nós esperados
  • ✅ Operadores são representados corretamente como BinOp

Tem outra questão para resolver?

Resolver agora com IA

Mais questões de Matemática

Ver mais Matemática resolvidas

Tem outra questão de Matemática?

Cole o enunciado, tire uma foto ou descreva o problema — a IA resolve com explicação completa em segundos.