summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgeno <gabriele.genovese2@studio.unibo.it>2024-06-28 12:23:28 +0200
committergeno <gabriele.genovese2@studio.unibo.it>2024-06-28 12:23:28 +0200
commit37665fb6d0bc1eb29396ae949354cf7d6f9d54ca (patch)
tree058204d723fb31b3b30bf8d141cf621c6f42c0c6
parent1d5c4862e136419ab1ed3fcf8d8edaa0ee5fda10 (diff)
resolving all the comments santo made
-rw-r--r--src/Main.java15
-rw-r--r--src/ParseAll.java11
-rw-r--r--src/ast/Python3VisitorImpl.java19
-rw-r--r--src/ast/nodes/AtomNode.java4
-rw-r--r--src/ast/nodes/ExprListNode.java9
-rw-r--r--src/ast/nodes/ExprNode.java14
-rw-r--r--src/ast/nodes/ForStmtNode.java20
-rw-r--r--src/ast/nodes/TestlistCompNode.java11
-rw-r--r--src/ast/types/FunctionType.java9
-rw-r--r--src/semanticanalysis/Share.java33
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();
+ }
}