private void setVariablesType(ArrayList<Node> variables) { variables.forEach( (v) -> { Node type = v.getChildren().get(1); Node listId = v.getChildren().get(0); listId .getChildren() .forEach( (id) -> { int tag = 0; if (type.getTag() == Tag.REAL) { tag = Tag.REAL_NUM; } else { if (type.getTag() == Tag.INTEGER) { tag = Tag.INT_NUM; } else { tag = Tag.BOOL_NUM; } } syntaxAnalyser.setVariableType(new Word(id.getStrValue(), id.getTag()), tag); }); }); }
public int check(Node root) throws SemanticException { if (root.getType() == 0) { switch (root.getTag()) { case Tag.STRUCTERED_STATEMENT: int tag = root.getChildren().get(0).getTag(); if (tag == Tag.BEGIN) { root.getChildren() .get(1) .getChildren() .forEach( (node) -> { try { check(node.getChildren().get(0)); } catch (SemanticException e) { e.printStackTrace(); System.exit(1); } }); } else { if (tag == Tag.WHILE) { if (check(root.getChildren().get(1)) != Tag.BOOL_NUM) { throw new SemanticException( "Semantic error in line " + root.getNumLine() + ", unexpected type, expected type 'boolean'."); } check( root.getChildren() .get(3) .getChildren() .get(0)); // Проверяем statement->(simple-statement | structured-statement) } else { if (tag == Tag.WRITELN) { check(root.getChildren().get(1)); } else { if (check(root.getChildren().get(1)) != Tag.BOOL_NUM) { throw new SemanticException( "Semantic error in line " + root.getNumLine() + ", unexpected type, expected type 'boolean'."); } check(root.getChildren().get(3).getChildren().get(0)); if (root.getChildren().size() > 4) { check(root.getChildren().get(5).getChildren().get(0)); } } } } break; case Tag.SIMPLE_STATEMENT: int tagId = check(root.getChildren().get(0)); int tagExpr = check(root.getChildren().get(2)); if (!checkTags(tagId, tagExpr)) { throw new SemanticException( "Semantic error in line " + root.getNumLine() + ", unexpected type."); } root.setType(tagId); break; case Tag.ID: root.setType( syntaxAnalyser.getVariables().get(new Word(root.getStrValue(), root.getTag()))); break; case Tag.EXPRESSION: if (root.getChildren().size() > 1) { int tag1 = check(root.getChildren().get(0)); int tag2 = check(root.getChildren().get(2)); if (!checkTagsExpr(tag1, tag2)) { throw new SemanticException( "Semantic error in line " + root.getNumLine() + ", unexpected type."); } root.setType(Tag.BOOL_NUM); } else { root.setType(check(root.getChildren().get(0))); } break; case Tag.SIMPLE_EXPRESSION: if (root.getChildren().size() <= 2) { int index = 0; if (root.getChildren().get(0).getTag() != Tag.TERM) { index = 1; } root.setType(check(root.getChildren().get(index))); } else { for (Node node : root.getChildren()) { if (node.getTag() == Tag.TERM) { int type = check(node); if (type == Tag.BOOL_NUM) { throw new SemanticException( "Semantic error in line " + root.getNumLine() + ", unexpected type."); } if (type == Tag.REAL_NUM) { root.setType(type); } } } if (root.getType() == 0) { root.setType(Tag.INT_NUM); } } break; case Tag.TERM: if (root.getChildren().size() == 1) { root.setType(check(root.getChildren().get(0))); } else { int index = 0; for (Node node : root.getChildren()) { if (node.getTag() == Tag.FACTOR) { int type = check(node); if (type == Tag.BOOL_NUM) { throw new SemanticException( "Semantic error in line " + root.getNumLine() + ", unexpected type."); } if (type == Tag.REAL_NUM) { root.setType(type); } } if (node.getTag() == Tag.DIV) { root.setType(Tag.REAL_NUM); } if (node.getTag() == Tag.IDIV || node.getTag() == Tag.IMOD) { if (root.getChildren().get(index - 1).getType() != Tag.INT_NUM || check(root.getChildren().get(index + 1)) != Tag.INT_NUM) { throw new SemanticException( "Semantic error in line " + root.getNumLine() + ", unexpected type."); } } index++; } if (root.getType() == 0) { root.setType(Tag.INT_NUM); } } break; case Tag.FACTOR: if (root.getChildren().get(0).getTag() == Tag.LEFT_PARENTHESIS) { root.setType(check(root.getChildren().get(1))); } else { if (root.getChildren().get(0).getTag() == Tag.ID) { root.setType(check(root.getChildren().get(0))); } else { if (root.getChildren().get(0).getTag() == Tag.SQRT) { root.setType(check(root.getChildren().get(1))); } else { root.setType(root.getChildren().get(0).getType()); } } } break; } } return root.getType(); }