diff options
author | geno <gabriele.genovese2@studio.unibo.it> | 2024-06-27 20:49:56 +0200 |
---|---|---|
committer | geno <gabriele.genovese2@studio.unibo.it> | 2024-06-27 20:49:56 +0200 |
commit | fd85e9980c0305c6dfb91aaeb199430a89163c3e (patch) | |
tree | 724d7184c11ad3acb8a8b0d2e15f1922f5b36059 | |
parent | 4898724edf343650ffb80792caf9e242e5843059 (diff) |
fixed comp_for and added reseved word type
-rw-r--r-- | src/ast/Python3VisitorImpl.java | 44 | ||||
-rw-r--r-- | src/ast/nodes/ArglistNode.java | 38 | ||||
-rw-r--r-- | src/ast/nodes/AtomNode.java | 13 | ||||
-rw-r--r-- | src/ast/nodes/CompForNode.java | 59 | ||||
-rw-r--r-- | src/ast/nodes/CompIterNode.java | 50 | ||||
-rw-r--r-- | src/ast/nodes/TestlistCompNode.java | 19 | ||||
-rw-r--r-- | src/ast/types/NoneType.java | 16 | ||||
-rw-r--r-- | src/ast/types/ReservedWordsType.java (renamed from src/ast/types/ContinueBreakType.java) | 4 |
8 files changed, 213 insertions, 30 deletions
diff --git a/src/ast/Python3VisitorImpl.java b/src/ast/Python3VisitorImpl.java index 5b812ea..c5f1bfa 100644 --- a/src/ast/Python3VisitorImpl.java +++ b/src/ast/Python3VisitorImpl.java @@ -434,6 +434,8 @@ public class Python3VisitorImpl extends Python3ParserBaseVisitor<Node> { Testlist_compContext tlc = ctx.testlist_comp(); if (ctx.NUMBER() != null) { return new AtomNode(ctx.NUMBER().toString(), null); + } else if (ctx.NONE() != null) { + return new AtomNode(ctx.NONE().toString(), null); } else if (ctx.TRUE() != null) { return new AtomNode(ctx.TRUE().toString(), null); } else if (ctx.FALSE() != null) { @@ -453,7 +455,7 @@ public class Python3VisitorImpl extends Python3ParserBaseVisitor<Node> { } else if (ctx.OPEN_PAREN() != null && ctx.CLOSE_PAREN() != null) { return manageTlc(tlc); } - return new AtomNode(ctx.NONE().toString(), null); + return new AtomNode(null, null); } public AtomNode manageTlc(Testlist_compContext tlc) { @@ -533,7 +535,45 @@ public class Python3VisitorImpl extends Python3ParserBaseVisitor<Node> { for (ExprContext c : ctx.expr()) { exprlist.add(visit(c)); } + Comp_forContext cfc = ctx.comp_for(); + if (cfc != null) { + Node comp = visit(ctx.comp_for()); + return new TestlistCompNode(exprlist, comp); + } + return new TestlistCompNode(exprlist, null); + } + + /** + * Returns a `CompForNode`. + * + * ``` comp_for : 'for' exprlist 'in' expr comp_iter? ;``` + */ + public Node visitComp_for(Comp_forContext ctx) { + Node exprlist = visit(ctx.exprlist()); + Node expr = visit(ctx.expr()); + Comp_iterContext cic = ctx.comp_iter(); - return new TestlistCompNode(exprlist); + if (cic != null) { + Node comp = visit(ctx.comp_iter()); + return new CompForNode(exprlist, expr, comp); + } + return new CompForNode(exprlist, expr, null); + } + + /** + * Returns a `CompIterNode`. + * + * ``` comp_iter : comp_for | comp_if ; ;``` + */ + public Node visitComp_iter(Comp_iterContext ctx) { + // TODO: Implement comp_if + // Node iter = visit(ctx.comp_if()); + Comp_forContext cfc = ctx.comp_for(); + if (cfc != null) { + Node forNode = visit(ctx.comp_for()); + return new CompIterNode(forNode); + + } + return new CompIterNode(null); } } diff --git a/src/ast/nodes/ArglistNode.java b/src/ast/nodes/ArglistNode.java index 983d150..c29a4e0 100644 --- a/src/ast/nodes/ArglistNode.java +++ b/src/ast/nodes/ArglistNode.java @@ -22,25 +22,27 @@ public class ArglistNode implements Node { ArrayList<SemanticError> errors = new ArrayList<SemanticError>(); for (var arg : arguments) { - ExprNode argExpr = (ExprNode) arg; - String argName = argExpr.getId(); - - // TODO: check fucking IntType for params - // TODO: remove fucking comments - if (argName != null) { - if (Arrays.asList(bif).contains(argName)) { - continue; + if (arg instanceof ExprNode) { + ExprNode argExpr = (ExprNode) arg; + String argName = argExpr.getId(); + + // TODO: check fucking IntType for params + // TODO: remove fucking comments + if (argName != null) { + if (Arrays.asList(bif).contains(argName)) { + continue; + } + + if (ST.lookup(argName) != null && ST.lookup(argName).getType() instanceof ImportType) { + continue; + } + + if (ST.nslookup(argName) < 0 && argExpr.typeCheck() instanceof AtomType) { + errors.add(new SemanticError("name '" + argName + "' is not defined.")); + } + } else { + errors.addAll(arg.checkSemantics(ST, _nesting)); } - - if (ST.lookup(argName) != null && ST.lookup(argName).getType() instanceof ImportType) { - continue; - } - - if (ST.nslookup(argName) < 0 && argExpr.typeCheck() instanceof AtomType) { - errors.add(new SemanticError("name '" + argName + "' is not defined.")); - } - } else { - errors.addAll(arg.checkSemantics(ST, _nesting)); } } diff --git a/src/ast/nodes/AtomNode.java b/src/ast/nodes/AtomNode.java index 592aac4..16281d6 100644 --- a/src/ast/nodes/AtomNode.java +++ b/src/ast/nodes/AtomNode.java @@ -50,23 +50,28 @@ public class AtomNode implements Node { return new VoidType(); } + Pattern noneVariable = Pattern.compile("^(None)$"); Pattern booleanVariable = Pattern.compile("^(True|False)$"); - Pattern continueBreakVariable = Pattern.compile("^(continue|break)$"); + Pattern reservedWords = Pattern.compile("^(continue|break|int|float)$"); // this regex should match every possible atom name written in this format: CHAR (CHAR | DIGIT)* Pattern simpleVariable = Pattern.compile("^[a-zA-Z][a-zA-Z0-9]*$", Pattern.CASE_INSENSITIVE); + Matcher noneVariableMatcher = noneVariable.matcher(this.val); Matcher booleanVariableMatcher = booleanVariable.matcher(this.val); - Matcher continueBreakVariableMatcher = continueBreakVariable.matcher(this.val); + Matcher reservedWordsMatcher = reservedWords.matcher(this.val); Matcher simpleVariableMatcher = simpleVariable.matcher(this.val); + boolean matchFoundNone = noneVariableMatcher.find(); boolean matchFoundBoolean = booleanVariableMatcher.find(); - boolean matchFoundContinueBreak = continueBreakVariableMatcher.find(); + boolean matchFoundContinueBreak = reservedWordsMatcher.find(); boolean matchFoundSimpleVariable = simpleVariableMatcher.find(); if (matchFoundBoolean) { return new BoolType(); } else if (matchFoundContinueBreak) { - return new ContinueBreakType(); + return new ReservedWordsType(); + } else if (matchFoundNone) { + return new NoneType(); } else if (matchFoundSimpleVariable) { return new AtomType(); // could be a variable or a fuction } else { diff --git a/src/ast/nodes/CompForNode.java b/src/ast/nodes/CompForNode.java new file mode 100644 index 0000000..d5c50d6 --- /dev/null +++ b/src/ast/nodes/CompForNode.java @@ -0,0 +1,59 @@ +package ast.nodes; + +import ast.types.*; +import java.util.ArrayList; +import java.util.Arrays; +import semanticanalysis.SemanticError; +import semanticanalysis.SymbolTable; + +/** + * Node for the `comp_for` statement of the grammar. 'for' exprlist 'in' expr + * comp_iter? + */ +public class CompForNode implements Node { + + protected ExprListNode exprlist; + protected ExprNode single_expr; + protected CompIterNode comp_iter; + + public CompForNode(Node exprlist, Node single_expr, Node comp_iter) { + this.exprlist = (ExprListNode) exprlist; + this.single_expr = (ExprNode) single_expr; + this.comp_iter = (CompIterNode) comp_iter; + } + + @Override + public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) { + ArrayList<SemanticError> errors = new ArrayList<SemanticError>(); + + errors.addAll(exprlist.checkSemantics(ST, _nesting)); + errors.addAll(single_expr.checkSemantics(ST, _nesting)); + if (comp_iter != null) { + errors.addAll(comp_iter.checkSemantics(ST, _nesting)); + } + return errors; + } + + @Override + public Type typeCheck() { + return new VoidType(); + } + + // TODO: add code generation for arglist node + @Override + public String codeGeneration() { + return ""; + } + + @Override + public String toPrint(String prefix) { + String str = prefix + "CompForNode\n"; + + prefix += " "; + str += exprlist.toPrint(prefix); + str += single_expr.toPrint(prefix); + str += comp_iter.toPrint(prefix); + return str; + } + +} diff --git a/src/ast/nodes/CompIterNode.java b/src/ast/nodes/CompIterNode.java new file mode 100644 index 0000000..6704bd7 --- /dev/null +++ b/src/ast/nodes/CompIterNode.java @@ -0,0 +1,50 @@ +package ast.nodes; + +import ast.types.*; +import java.util.ArrayList; +import semanticanalysis.SemanticError; +import semanticanalysis.SymbolTable; + +/** + * Node for the `comp_iter` statement of the grammar. + */ +public class CompIterNode implements Node { + + protected CompForNode comp_for; + // protected CompIfNode compIfNode; + + public CompIterNode(Node comp_for) { + this.comp_for = (CompForNode) comp_for; + } + + @Override + public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) { + ArrayList<SemanticError> errors = new ArrayList<SemanticError>(); + + if (comp_for != null) { + errors.addAll(comp_for.checkSemantics(ST, _nesting)); + } + return errors; + } + + @Override + public Type typeCheck() { + return new VoidType(); + } + + // TODO: add code generation for arglist node + @Override + public String codeGeneration() { + return ""; + } + + @Override + public String toPrint(String prefix) { + String str = prefix + "CompIterNode\n"; + + prefix += " "; + str += comp_for.toPrint(prefix); + return str; + } + +} diff --git a/src/ast/nodes/TestlistCompNode.java b/src/ast/nodes/TestlistCompNode.java index 070b1a1..bcaca83 100644 --- a/src/ast/nodes/TestlistCompNode.java +++ b/src/ast/nodes/TestlistCompNode.java @@ -11,17 +11,28 @@ import semanticanalysis.SymbolTable; public class TestlistCompNode implements Node { private final ArrayList<Node> exprs; + private final CompForNode comp; - public TestlistCompNode(ArrayList<Node> _exprs) { - this.exprs = _exprs; + public TestlistCompNode(ArrayList<Node> exprs, Node comp) { + this.exprs = exprs; + this.comp = (CompForNode) comp; } @Override public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) { ArrayList<SemanticError> errors = new ArrayList(); - for (var param : exprs) { - errors.addAll(param.checkSemantics(ST, _nesting)); + if (comp != null) { + // if comp is set, then we save the atom in the ST (we assume the first expr is an atom) + String id = ((ExprNode) exprs.get(0)).getId(); + Type t = ((ExprNode) exprs.get(0)).typeCheck(); + ST.insert(id, t, _nesting, ""); + // errors.addAll(comp.checkSemantics(ST, _nesting)); + } else { + // if comp is not set, then exprs is a list of 1 or more element + for (var param : exprs) { + errors.addAll(param.checkSemantics(ST, _nesting)); + } } return errors; diff --git a/src/ast/types/NoneType.java b/src/ast/types/NoneType.java new file mode 100644 index 0000000..42f7fd7 --- /dev/null +++ b/src/ast/types/NoneType.java @@ -0,0 +1,16 @@ +package ast.types; + +/** + * A none type. None return unit. + */ +public class NoneType extends Type { + + public String toPrint(String prefix) { + return prefix + "None\n"; + } + + @Override + public String toString() { + return "None"; + } +} diff --git a/src/ast/types/ContinueBreakType.java b/src/ast/types/ReservedWordsType.java index dfcf1f2..f5f7ac5 100644 --- a/src/ast/types/ContinueBreakType.java +++ b/src/ast/types/ReservedWordsType.java @@ -3,8 +3,8 @@ package ast.types; /** * A type for the continue and break statements. */ -public class ContinueBreakType extends Type { +public class ReservedWordsType extends Type { public String toPrint(String prefix) { - return prefix + "ContinueBreak\n"; + return prefix + "ReservedWords\n"; } } |