diff options
author | geno <gabriele.genovese2@studio.unibo.it> | 2024-06-28 12:23:28 +0200 |
---|---|---|
committer | geno <gabriele.genovese2@studio.unibo.it> | 2024-06-28 12:23:28 +0200 |
commit | 37665fb6d0bc1eb29396ae949354cf7d6f9d54ca (patch) | |
tree | 058204d723fb31b3b30bf8d141cf621c6f42c0c6 | |
parent | 1d5c4862e136419ab1ed3fcf8d8edaa0ee5fda10 (diff) |
resolving all the comments santo made
-rw-r--r-- | src/Main.java | 15 | ||||
-rw-r--r-- | src/ParseAll.java | 11 | ||||
-rw-r--r-- | src/ast/Python3VisitorImpl.java | 19 | ||||
-rw-r--r-- | src/ast/nodes/AtomNode.java | 4 | ||||
-rw-r--r-- | src/ast/nodes/ExprListNode.java | 9 | ||||
-rw-r--r-- | src/ast/nodes/ExprNode.java | 14 | ||||
-rw-r--r-- | src/ast/nodes/ForStmtNode.java | 20 | ||||
-rw-r--r-- | src/ast/nodes/TestlistCompNode.java | 11 | ||||
-rw-r--r-- | src/ast/types/FunctionType.java | 9 | ||||
-rw-r--r-- | src/semanticanalysis/Share.java | 33 |
10 files changed, 98 insertions, 47 deletions
diff --git a/src/Main.java b/src/Main.java index 04f7183..4f5d45f 100644 --- a/src/Main.java +++ b/src/Main.java @@ -1,7 +1,4 @@ -import java.io.BufferedReader; -import java.io.FileReader; -import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import javax.swing.*; @@ -27,7 +24,7 @@ public class Main { try { String fileStr = args[0]; System.out.println(fileStr); - System.out.println(readFile(fileStr)); + System.out.println(Share.readFile(fileStr)); CharStream cs = CharStreams.fromFileName(fileStr); Python3Lexer lexer = new Python3Lexer(cs); CommonTokenStream tokens = new CommonTokenStream(lexer); @@ -71,14 +68,4 @@ public class Main { } } - private static String readFile(String filePath) throws IOException { - StringBuilder content = new StringBuilder(); - try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) { - String line; - while ((line = reader.readLine()) != null) { - content.append(line).append("\n"); - } - } - return content.toString(); - } } diff --git a/src/ParseAll.java b/src/ParseAll.java index 2662a85..568c89c 100644 --- a/src/ParseAll.java +++ b/src/ParseAll.java @@ -22,7 +22,7 @@ public class ParseAll { // fileStr = "./progs/wrong.py"; try { - if (!file.isFile() || !getExtension(file.getName()).equals("py")) { + if (!file.isFile() || !Share.getExtension(file.getName()).equals("py")) { System.err.println("Wont parse: " + fileStr); continue; } @@ -56,13 +56,4 @@ public class ParseAll { } } } - - public static String getExtension(String fileName) { - int extensionIndex = fileName.lastIndexOf('.'); - if (extensionIndex == -1) { - return fileName; - } else { - return fileName.substring(extensionIndex + 1); - } - } } diff --git a/src/ast/Python3VisitorImpl.java b/src/ast/Python3VisitorImpl.java index 42e2537..1cf15b7 100644 --- a/src/ast/Python3VisitorImpl.java +++ b/src/ast/Python3VisitorImpl.java @@ -424,7 +424,7 @@ public class Python3VisitorImpl extends Python3ParserBaseVisitor<Node> { } /** - * Returns an `AtomNode`. FIXME: add support for testlist_comp + * Returns an `AtomNode`. * * ``` atom : '(' testlist_comp? ')' | '[' testlist_comp? ']' | '{' * testlist_comp? '}' | NAME | NUMBER | STRING+ | '...' | 'None' | 'True' | @@ -449,22 +449,26 @@ public class Python3VisitorImpl extends Python3ParserBaseVisitor<Node> { } return new AtomNode(varName, null); } else if (ctx.OPEN_BRACE() != null && ctx.CLOSE_BRACE() != null) { - return manageTlc(tlc); + return manageCompListContext(tlc); } else if (ctx.OPEN_BRACK() != null && ctx.CLOSE_BRACK() != null) { - return manageTlc(tlc); + return manageCompListContext(tlc); } else if (ctx.OPEN_PAREN() != null && ctx.CLOSE_PAREN() != null) { - return manageTlc(tlc); + return manageCompListContext(tlc); } return new AtomNode(null, null); } - public AtomNode manageTlc(Testlist_compContext tlc) { + /** + * Supporting function for `visitAtom`. Returns an `AtomNode` with + * `testlist_comp` set if the context is not null. Otherwise, returns an + * `AtomNode` with nulls. + */ + public AtomNode manageCompListContext(Testlist_compContext tlc) { if (tlc != null) { Node testlist_comp = visit(tlc); return new AtomNode(null, testlist_comp); - } else { - return new AtomNode(null, null); } + return new AtomNode(null, null); } /** @@ -529,7 +533,6 @@ public class Python3VisitorImpl extends Python3ParserBaseVisitor<Node> { * ``` testlist_comp : expr (comp_for | (',' expr)* ','?) ; ``` */ public Node visitTestlist_comp(Testlist_compContext ctx) { - // TODO: implement comp_for ArrayList<Node> exprlist = new ArrayList<Node>(); for (ExprContext c : ctx.expr()) { diff --git a/src/ast/nodes/AtomNode.java b/src/ast/nodes/AtomNode.java index cea617f..fef72ec 100644 --- a/src/ast/nodes/AtomNode.java +++ b/src/ast/nodes/AtomNode.java @@ -20,6 +20,10 @@ public class AtomNode implements Node { this.exprlist = (TestlistCompNode) exprlist; } + /** + * Returns the identifier of the `AtomNode` if it's not `null`, otherwise + * returns `null`. + */ public String getId() { return this.val; } diff --git a/src/ast/nodes/ExprListNode.java b/src/ast/nodes/ExprListNode.java index acdf679..800f4be 100644 --- a/src/ast/nodes/ExprListNode.java +++ b/src/ast/nodes/ExprListNode.java @@ -31,7 +31,14 @@ public class ExprListNode implements Node { return exprs.size(); } + /** + * Returns the i-th expressions of `exprs` field. If the index is greater or + * equals than the size return `null`. + */ public Node getElem(int i) { + if (i >= this.exprs.size()) { + return null; + } return exprs.get(i); } @@ -48,7 +55,7 @@ public class ExprListNode implements Node { @Override public String toPrint(String prefix) { - String str = prefix + "Paramlist\n"; + String str = prefix + "ExprList\n"; prefix += " "; for (var param : exprs) { diff --git a/src/ast/nodes/ExprNode.java b/src/ast/nodes/ExprNode.java index 591ee37..8e3b896 100644 --- a/src/ast/nodes/ExprNode.java +++ b/src/ast/nodes/ExprNode.java @@ -26,6 +26,10 @@ public class ExprNode implements Node { this.trailers = trailers; } + /** + * Returns the i-th expressions of `exprs` field. If the index is greater or + * equals than the size return `null`. + */ public Node getExpr(int i) { if (i >= this.exprs.size()) { return null; @@ -34,6 +38,10 @@ public class ExprNode implements Node { return this.exprs.get(i); } + /** + * Returns the identifier of the `AtomNode` if it's not `null`, otherwise + * returns `null`. + */ public String getId() { if (atom != null) { return ((AtomNode) this.atom).getId(); @@ -65,6 +73,7 @@ public class ExprNode implements Node { for (var t : trailers) { errors.addAll(t.checkSemantics(ST, _nesting)); } + } else { FunctionType ft = (FunctionType) fun.getType(); int paramNumber = ft.getParamNumber(); @@ -80,6 +89,7 @@ public class ExprNode implements Node { for (var trailer : trailers) { errors.addAll(trailer.checkSemantics(ST, _nesting)); } + } } else if (atom != null) { errors.addAll(atom.checkSemantics(ST, _nesting)); @@ -126,11 +136,11 @@ public class ExprNode implements Node { } for (var expr : exprs) { - str += expr.toPrint(prefix); + str = expr.toPrint(prefix); } for (var trailer : trailers) { - str += trailer.toPrint(prefix); + str = trailer.toPrint(prefix); } if (op != null) { diff --git a/src/ast/nodes/ForStmtNode.java b/src/ast/nodes/ForStmtNode.java index c5301ee..d4c5e56 100644 --- a/src/ast/nodes/ForStmtNode.java +++ b/src/ast/nodes/ForStmtNode.java @@ -18,18 +18,38 @@ public class ForStmtNode implements Node { this.block = block; } + /** + * This methods check the semantics of the operation `for i in list: block`. + * + * After the `for` keyword, it's parsed as a list of expression. We verified + * that the last expression is always gonna be `expr comp_op expr`. We + * comp_op must be the `in` keyword. `i` could be of any lenght (e.g. `a, b, + * c`). + * + * In this function we define the following approch: we save in the + * SymbolTable every atom until the last expression in the expression's + * list. For the last element, we know that is in the `expr comp_op expr` + * format, so we take the left element and save it in the SymbolicTable as + * an atom. + */ @Override public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) { ArrayList<SemanticError> errors = new ArrayList<SemanticError>(); + // Save every atom in the expression's list, except the last one var l = (ExprListNode) exprList; for (int i = 0; i < l.getSize() - 1; ++i) { var e = (ExprNode) l.getElem(i); ST.insert(e.getId(), e.typeCheck(), _nesting, ""); } + // Manage the last expression of expression's list + // Get the ExprNode var left = (ExprNode) l.getElem(l.getSize() - 1); + // Get the left side expression of the operation, that + // corresponds to the first element of the expression list. var atomLeft = (ExprNode) left.getExpr(0); + // ENHANCE: check that the comp_op is the `in` keyword ST.insert(atomLeft.getId(), atomLeft.typeCheck(), _nesting, ""); errors.addAll(exprList.checkSemantics(ST, _nesting)); diff --git a/src/ast/nodes/TestlistCompNode.java b/src/ast/nodes/TestlistCompNode.java index 4ae77c9..244f4ef 100644 --- a/src/ast/nodes/TestlistCompNode.java +++ b/src/ast/nodes/TestlistCompNode.java @@ -10,8 +10,8 @@ import semanticanalysis.SymbolTable; */ public class TestlistCompNode implements Node { - private final ArrayList<Node> exprs; - private final CompForNode comp; + private ArrayList<Node> exprs; + private CompForNode comp; public TestlistCompNode(ArrayList<Node> exprs, Node comp) { this.exprs = exprs; @@ -45,7 +45,14 @@ public class TestlistCompNode implements Node { return exprs.size(); } + /** + * Returns the i-th expressions of `exprs` field. If the index is greater or + * equals than the size return `null`. + */ public Node getElem(int i) { + if (i >= this.exprs.size()) { + return null; + } return exprs.get(i); } diff --git a/src/ast/types/FunctionType.java b/src/ast/types/FunctionType.java index 464bb9c..ef50641 100644 --- a/src/ast/types/FunctionType.java +++ b/src/ast/types/FunctionType.java @@ -1,18 +1,19 @@ package ast.types; /** - * An tom type. TODO: do I need to use this one? + * A Function type. */ public class FunctionType extends Type { - private final int paramNumber; - private final Type returnType; + private int paramNumber; + private Type returnType; public FunctionType(int paramNumber, Type returnType) { this.paramNumber = paramNumber; this.returnType = returnType; } + // Return the length of the parameters public int getParamNumber() { return paramNumber; } @@ -22,6 +23,6 @@ public class FunctionType extends Type { } public String toPrint(String prefix) { - return prefix + "Atom\n"; + return prefix + "Function\n"; } } diff --git a/src/semanticanalysis/Share.java b/src/semanticanalysis/Share.java index c1f03c2..c98fc53 100644 --- a/src/semanticanalysis/Share.java +++ b/src/semanticanalysis/Share.java @@ -1,13 +1,18 @@ package semanticanalysis; -import java.util.ArrayList; +import java.util.*; +import java.io.*; public class Share { - public static <T> ArrayList<T> removeDuplicates(ArrayList<T> list) { - ArrayList<T> newList = new ArrayList<T>(); + /** + * Removes the duplicate elements in a list of Semantic Errors. It's not + * generic because it's used a custom contains function. + */ + public static ArrayList<SemanticError> removeDuplicates(ArrayList<SemanticError> list) { + ArrayList<SemanticError> newList = new ArrayList<SemanticError>(); - for (T element : list) { + for (SemanticError element : list) { if (!customContains(newList, element)) { newList.add(element); } @@ -15,9 +20,14 @@ public class Share { return newList; } - public static <T> boolean customContains(ArrayList<T> list, T e) { + /** + * Normal contains did not work, so we made a custom contains function. + * Returns `true` if the String rappresentation of an object in the list is + * equal to the element given in input. + */ + private static boolean customContains(ArrayList<SemanticError> list, SemanticError e) { String e1 = e.toString(); - for (T element : list) { + for (SemanticError element : list) { String e2 = element.toString(); if (e2.equals(e1)) { return true; @@ -34,4 +44,15 @@ public class Share { return fileName.substring(extensionIndex + 1); } } + + public static String readFile(String filePath) throws IOException { + StringBuilder content = new StringBuilder(); + try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) { + String line; + while ((line = reader.readLine()) != null) { + content.append(line).append("\n"); + } + } + return content.toString(); + } } |