Advertisement
AleksandarH

ParserImpl.java

Dec 1st, 2023
753
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 18.76 KB | None | 0 0
  1. package parser;
  2.  
  3. import bg.tu_varna.kst_sit.ci_ep.ast.*;
  4. import bg.tu_varna.kst_sit.ci_ep.ast.assignable.ArrayInitNode;
  5. import bg.tu_varna.kst_sit.ci_ep.ast.assignable.AssignableNode;
  6. import bg.tu_varna.kst_sit.ci_ep.ast.assignable.CharacterLiteralNode;
  7. import bg.tu_varna.kst_sit.ci_ep.ast.assignable.StringLiteralNode;
  8. import bg.tu_varna.kst_sit.ci_ep.ast.assignable.expression.*;
  9. import bg.tu_varna.kst_sit.ci_ep.ast.assignable.expression.operators.binary_operators.additive_operators.AdditionNode;
  10. import bg.tu_varna.kst_sit.ci_ep.ast.assignable.expression.operators.binary_operators.additive_operators.SubtractionNode;
  11. import bg.tu_varna.kst_sit.ci_ep.ast.assignable.expression.operators.binary_operators.logical_operators.AndNode;
  12. import bg.tu_varna.kst_sit.ci_ep.ast.assignable.expression.operators.binary_operators.logical_operators.OrNode;
  13. import bg.tu_varna.kst_sit.ci_ep.ast.assignable.expression.operators.binary_operators.multiplicative_operators.DivisionNode;
  14. import bg.tu_varna.kst_sit.ci_ep.ast.assignable.expression.operators.binary_operators.multiplicative_operators.ModNode;
  15. import bg.tu_varna.kst_sit.ci_ep.ast.assignable.expression.operators.binary_operators.multiplicative_operators.MultiplicationNode;
  16. import bg.tu_varna.kst_sit.ci_ep.ast.assignable.expression.operators.binary_operators.relational_operators.*;
  17. import bg.tu_varna.kst_sit.ci_ep.ast.assignable.expression.operators.unary_operators.MinusNode;
  18. import bg.tu_varna.kst_sit.ci_ep.ast.assignable.expression.operators.unary_operators.NotNode;
  19. import bg.tu_varna.kst_sit.ci_ep.ast.global_definition.FunctionDefinitionNode;
  20. import bg.tu_varna.kst_sit.ci_ep.ast.global_definition.GlobalDefinitionNode;
  21. import bg.tu_varna.kst_sit.ci_ep.ast.global_definition.VariableDefinitionNode;
  22. import bg.tu_varna.kst_sit.ci_ep.ast.statement.*;
  23. import bg.tu_varna.kst_sit.ci_ep.ast.type.PrimitiveTypeNode;
  24. import bg.tu_varna.kst_sit.ci_ep.ast.type.TypeNode;
  25. import bg.tu_varna.kst_sit.ci_ep.ast.type.VoidTypeNode;
  26. import bg.tu_varna.kst_sit.ci_ep.exceptions.SyntaxException;
  27. import bg.tu_varna.kst_sit.ci_ep.lexer.Lexer;
  28. import bg.tu_varna.kst_sit.ci_ep.lexer.token.Token;
  29. import bg.tu_varna.kst_sit.ci_ep.parser.Parser;
  30. import bg.tu_varna.kst_sit.ci_ep.source.SourceImpl;
  31. import bg.tu_varna.kst_sit.ci_ep.utils.CompilerTestHelper;
  32. import lexer.LexerImpl;
  33. import token.TokenType;
  34.  
  35. import java.io.IOException;
  36. import java.util.ArrayList;
  37. import java.util.List;
  38.  
  39. public class ParserImpl extends Parser<TokenType, AST> {
  40.  
  41.     public ParserImpl(Lexer<TokenType> lexer) {
  42.         super(lexer);
  43.     }
  44.  
  45.     private void accept(TokenType tokenType) {
  46.         if (currentToken.getTokenType() != tokenType) {
  47.             throw new SyntaxException("Token doesn't match! Expected " +
  48.                     tokenType.value + ", Got " + currentToken.getTokenType().value, currentToken);
  49.         }
  50.         currentToken = lexer.nextToken();
  51.     }
  52.  
  53.     @Override
  54.     public AST entryRule() {
  55.         accept(TokenType.PROGRAM);
  56.         accept(TokenType.LBRACKET);
  57.         programBody();
  58.         accept(TokenType.RBRACKET);
  59.         return currentNode;
  60.     }
  61.  
  62.     void programBody() {
  63.         List<GlobalDefinitionNode> globalDefinitions = new ArrayList<>();
  64.         while(
  65.                 TokenType.isPrimitiveType(currentToken.getTokenType()) ||
  66.                         (currentToken.getTokenType() == TokenType.IDENTIFIER && !currentToken.getText().equals("main"))
  67.                 ) {
  68.             if (currentToken.getTokenType() == TokenType.IDENTIFIER) {
  69.                 functionDefinition();
  70.             } else {
  71.                 variableDefinition();
  72.                 accept(TokenType.SEMICOLON);
  73.             }
  74.             globalDefinitions.add((GlobalDefinitionNode) currentNode);
  75.         }
  76.         mainFunction();
  77.         globalDefinitions.add((GlobalDefinitionNode) currentNode);
  78.         currentNode = new ProgramBodyNode(null, globalDefinitions);
  79.     }
  80.  
  81.     void functionDefinition() {
  82.         Token token = currentToken;
  83.         accept(TokenType.IDENTIFIER);
  84.         accept(TokenType.LPAREN);
  85.  
  86.         FormalParameterNode formalParameters = null;
  87.         if (TokenType.isPrimitiveType(currentToken.getTokenType())) {
  88.             formalParameters();
  89.             formalParameters = (FormalParameterNode) currentNode;
  90.         }
  91.         accept(TokenType.RPAREN);
  92.         accept(TokenType.ARROW);
  93.         TypeNode typeNode;
  94.         if (currentToken.getTokenType() == TokenType.VOID) {
  95.             typeNode = new VoidTypeNode(currentToken);
  96.             accept(TokenType.VOID);
  97.         } else {
  98.             type();
  99.             typeNode = (TypeNode) currentNode;
  100.         }
  101.         block();
  102.         BlockNode blockNode = (BlockNode)currentNode;
  103.         currentNode = new FunctionDefinitionNode(token, formalParameters, typeNode, blockNode);
  104.     }
  105.  
  106.     void functionCall() {
  107.         accept(TokenType.AT);  
  108.         Token token = currentToken;
  109.         accept(TokenType.IDENTIFIER);
  110.         accept(TokenType.LPAREN);
  111.         ActualParameterNode actualParameters = null;
  112.         if (TokenType.isLiteralTerminal(currentToken.getTokenType())) {
  113.             actualParameters();
  114.             actualParameters = (ActualParameterNode) currentNode;
  115.         }
  116.         accept(TokenType.RPAREN);
  117.         currentNode = new FunctionCall(token, actualParameters);
  118.     }
  119.  
  120.     void type() {
  121.         Token token = currentToken;
  122.         boolean isArray = false;
  123.         if (TokenType.isPrimitiveType(currentToken.getTokenType())) {
  124.             accept(currentToken.getTokenType());
  125.             if (currentToken.getTokenType() == TokenType.LSQUARE) {
  126.                 isArray = true;
  127.                 accept(TokenType.LSQUARE);
  128.                 accept(TokenType.RSQUARE);
  129.             }
  130.         } else {
  131.             throw new SyntaxException("Expected return type. Got " + currentToken.getTokenType().value, currentToken);
  132.         }
  133.         currentNode = new PrimitiveTypeNode(token, isArray);
  134.     }
  135.  
  136.     void formalParameters() {
  137.         List<TypedVariableNode> formalParameters = new ArrayList<>();
  138.         type();
  139.         formalParameters.add(new TypedVariableNode(null, (TypeNode) currentNode, new VariableNode(currentToken, null)));
  140.         accept(TokenType.IDENTIFIER);
  141.         while (currentToken.getTokenType() == TokenType.COMMA) {
  142.             accept(TokenType.COMMA);
  143.             type();
  144.             formalParameters.add(new TypedVariableNode(null, (TypeNode) currentNode, new VariableNode(currentToken, null)));
  145.             accept(TokenType.IDENTIFIER);
  146.     }
  147.     currentNode = new FormalParameterNode(null, formalParameters);
  148. }
  149.  
  150.     void actualParameters() {
  151.         List<AssignableNode> params = new ArrayList<>();
  152.         assignable();
  153.         params.add((AssignableNode) currentNode);
  154.         while(currentToken.getTokenType() == TokenType.COMMA) {
  155.             accept(TokenType.COMMA);
  156.             assignable();
  157.             params.add((AssignableNode) currentNode);
  158.         }
  159.         currentNode = new ActualParameterNode(null, params);
  160.     }
  161.  
  162.     void variableDefinition() {
  163.         type();
  164.         TypeNode type = (TypeNode)currentNode;
  165.         assignment();
  166.         currentNode = new VariableDefinitionNode(null, type, (AssignmentNode) currentNode);
  167.     }
  168.  
  169.     void assignment() {
  170.         variable();
  171.         VariableNode variable = (VariableNode) currentNode;
  172.         Token token = currentToken;
  173.         accept(TokenType.BECOMES);
  174.         if (TokenType.isPrimitiveType(currentToken.getTokenType())) {
  175.             arrayInitialization();
  176.         } else if (TokenType.CHAR_LITERAL == currentToken.getTokenType()) {
  177.             characterLiteral();
  178.         } else if (TokenType.STRING_LITERAL == currentToken.getTokenType()) {
  179.             stringLiteral();
  180.         } else {
  181.             expression();
  182.         }
  183.         AssignableNode assignable = (AssignableNode) currentNode;
  184.         currentNode = new AssignmentNode(token, variable, assignable);
  185.     }
  186.  
  187.     void arrayInitialization() {
  188.         Token token = currentToken;
  189.         ExpressionNode expression = null;
  190.         if (TokenType.isPrimitiveType(currentToken.getTokenType())) {
  191.             accept(currentToken.getTokenType());
  192.             accept(TokenType.LSQUARE);
  193.             expression();
  194.             expression = (ExpressionNode) currentNode;
  195.             accept(TokenType.RSQUARE);
  196.         } else {
  197.             System.out.println("Expected array initialization. Got " + currentToken.getTokenType());
  198.         }
  199.         currentNode = new ArrayInitNode(token, expression);
  200.     }
  201.  
  202.     void block() {
  203.         List<Statement> statements = new ArrayList<>();
  204.         accept(TokenType.LBRACKET);
  205.         while (TokenType.isStatementTerminal(currentToken.getTokenType())) {
  206.             statement();
  207.             statements.add((Statement) currentNode);
  208.         }
  209.         accept(TokenType.RBRACKET);
  210.         currentNode = new BlockNode(null, statements);
  211.     }
  212.  
  213.     void expression() {
  214.         simpleExpression();
  215.         Token<TokenType> token = currentToken;
  216.         ExpressionNode left = (ExpressionNode) currentNode;
  217.         if (TokenType.isRelationalOperator(currentToken.getTokenType())) {
  218.             ExpressionNode right;
  219.             ExpressionNode relationalOperator = null;
  220.             accept((currentToken.getTokenType()));
  221.             simpleExpression();
  222.             right = (ExpressionNode) currentNode;
  223.             switch (token.getTokenType()) {
  224.                 case EQUALS:        relationalOperator = new EqualsNode(token, left, right); break;
  225.                 case NOTEQUALS:     relationalOperator = new NotEqualNode(token, left, right); break;
  226.                 case GREATER:       relationalOperator = new GreaterNode(token, left, right); break;
  227.                 case GREATER_EQ:    relationalOperator = new GreaterOrEqualNode(token, left, right); break;
  228.                 case LESS:          relationalOperator = new LessNode(token, left, right); break;
  229.                 case LESS_EQ:       relationalOperator = new LessOrEqualNode(token, left, right); break;
  230.             }
  231.             currentNode = relationalOperator;
  232.         }
  233.     }
  234.  
  235.     void simpleExpression() {
  236.         signedTerm();
  237.         ExpressionNode left = (ExpressionNode) currentNode;
  238.         while (TokenType.isOperatorGroupOne(currentToken.getTokenType())) {
  239.             Token<TokenType> token = currentToken;
  240.            accept((currentToken.getTokenType()));
  241.             signedTerm();
  242.             ExpressionNode right = (ExpressionNode) currentNode;
  243.             ExpressionNode additiveOperator = null;
  244.             switch (token.getTokenType()) {
  245.                 case PLUS:  additiveOperator = new AdditionNode(token, left, right); break;
  246.                 case MINUS: additiveOperator = new SubtractionNode(token, left, right); break;
  247.                 case OR:    additiveOperator = new OrNode(token, left, right); break;
  248.             }
  249.             currentNode = left = additiveOperator;
  250.         }
  251.     }
  252.  
  253.    void signedTerm() {
  254.         Token<TokenType> token = null;
  255.         if (TokenType.isUnaryOperator(currentToken.getTokenType())) {
  256.             token = currentToken;
  257.             accept((currentToken.getTokenType()));
  258.         }
  259.         term();
  260.         ExpressionNode operand = (ExpressionNode) currentNode;
  261.         if (token != null) {
  262.             switch (token.getTokenType()) {
  263.                 case NOT: operand = new NotNode(token, operand); break;
  264.                 case MINUS: operand = new MinusNode(token, operand); break;
  265.             }
  266.         }
  267.         currentNode = operand;
  268.     }
  269.  
  270.     void term() {
  271.         factor();
  272.         ExpressionNode left = (ExpressionNode) currentNode;
  273.         while (TokenType.isOperatorGroupTwo(currentToken.getTokenType())) {
  274.             Token<TokenType> token = currentToken;
  275.             accept((currentToken.getTokenType()));
  276.             factor();
  277.             ExpressionNode right = (ExpressionNode) currentNode;
  278.             ExpressionNode multiplicativeOperator = null;
  279.             switch (token.getTokenType()) {
  280.                 case MUL: multiplicativeOperator = new MultiplicationNode(token, left, right); break;
  281.                 case DIV: multiplicativeOperator = new DivisionNode(token, left, right); break;
  282.                 case MOD: multiplicativeOperator = new ModNode(token, left, right); break;
  283.                 case AND: multiplicativeOperator = new AndNode(token, left, right); break;
  284.             }
  285.             currentNode = left = multiplicativeOperator;
  286.         }
  287.     }
  288.  
  289.     void factor() {
  290.         switch(currentToken.getTokenType()) {
  291.             case IDENTIFIER:    variable();
  292.                                 break;
  293.             case NUMBER:        currentNode = new IntegerNode(currentToken);
  294.                                 accept(TokenType.NUMBER);
  295.                                 break;
  296.             case TRUE:
  297.             case FALSE:         currentNode = new BooleanNode(currentToken);
  298.                                 accept((currentToken.getTokenType()));
  299.                                 break;
  300.             case LENGTH:        arrayLength();
  301.                                 break;
  302.             case LPAREN:        accept(TokenType.LPAREN);
  303.                                 expression();
  304.                                 accept(TokenType.RPAREN);
  305.                                 break;
  306.             case AT:            functionCall();
  307.                                 break;
  308.             default:   throw new SyntaxException("Expected factor. Got " + currentToken.getTokenType().value, currentToken);
  309.         }
  310.     }
  311.  
  312.     void variable() {
  313.         Token token = currentToken;
  314.         accept(TokenType.IDENTIFIER);
  315.         ExpressionNode expression = null;
  316.         if (currentToken.getTokenType() == TokenType.LSQUARE) {
  317.             accept(TokenType.LSQUARE);
  318.             simpleExpression();
  319.             expression = (ExpressionNode) currentNode;
  320.             accept(TokenType.RSQUARE);
  321.         }
  322.         currentNode = new VariableNode(token, expression);
  323.     }
  324.  
  325.     void mainFunction() {
  326.         Token token = currentToken;
  327.         accept(TokenType.IDENTIFIER);
  328.         accept(TokenType.LPAREN);
  329.         accept(TokenType.RPAREN);
  330.         accept(TokenType.ARROW);
  331.         TypeNode typeNode = new VoidTypeNode(currentToken);
  332.         accept(TokenType.VOID);
  333.         block();
  334.         currentNode = new FunctionDefinitionNode(token, null, typeNode, (BlockNode) currentNode);
  335.     }
  336.  
  337.     void statement() {
  338.         if (TokenType.isCompoundStatementTerminal(currentToken.getTokenType())) {
  339.             compoundStatement();
  340.         } else {
  341.             simpleStatement();
  342.             accept(TokenType.SEMICOLON);
  343.         }
  344.     }
  345.  
  346.     void simpleStatement() {
  347.         switch(currentToken.getTokenType()) {
  348.             case INT:
  349.             case CHAR:
  350.             case BOOLEAN:       variableDefinition();
  351.                                 break;
  352.             case IDENTIFIER:    assignment();
  353.                                 break;
  354.             case AT:            functionCall();
  355.                                 break;
  356.             case RETURN:        returnStatement();
  357.                                 break;
  358.             case PRINT:         printStatement();
  359.                                 break;
  360.             case READ:          readStatement();
  361.                                 break;
  362.             default: throw new SyntaxException("Expected simpleStatement. Got " + currentToken.getTokenType().value, currentToken);
  363.         }
  364.     }
  365.  
  366.     void compoundStatement() {
  367.         if (currentToken.getTokenType() == TokenType.IF) {
  368.             ifStatement();
  369.         } else {
  370.             whileStatement();
  371.         }
  372.     }
  373.    
  374.     void ifStatement() {
  375.         Token token = currentToken;
  376.         accept(TokenType.IF);
  377.         accept(TokenType.LPAREN);
  378.         expression();
  379.         ExpressionNode expressionNode = (ExpressionNode) currentNode;
  380.         accept(TokenType.RPAREN);
  381.         block();
  382.         BlockNode ifStatement = (BlockNode) currentNode;
  383.         BlockNode elseStatement = null;
  384.         if (currentToken.getTokenType() == TokenType.ELSE) {
  385.             accept(TokenType.ELSE);
  386.             block();
  387.             elseStatement = (BlockNode) currentNode;
  388.         }
  389.         currentNode = new IfStatementNode(token, expressionNode, ifStatement, elseStatement);
  390.     }
  391.  
  392.     void whileStatement() {
  393.         Token token = currentToken;
  394.         accept(TokenType.WHILE);
  395.         accept(TokenType.LPAREN);
  396.         expression();
  397.         ExpressionNode expressionNode = (ExpressionNode) currentNode;
  398.         accept(TokenType.RPAREN);
  399.         block();
  400.         BlockNode blockNode = (BlockNode) currentNode;
  401.         currentNode = new WhileStatementNode(token, expressionNode, blockNode);
  402.     }
  403.    
  404.     void returnStatement() {
  405.         Token token = currentToken;
  406.         accept(TokenType.RETURN);
  407.         AssignableNode assignable = null;
  408.         if (TokenType.isLiteralTerminal(currentToken.getTokenType())) {
  409.             assignable();
  410.             assignable = (AssignableNode) currentNode;
  411.         }
  412.         currentNode = new ReturnStatementNode(token, assignable);
  413.     }
  414.    
  415.     void printStatement() {
  416.         Token token = currentToken;
  417.         accept(TokenType.PRINT);
  418.         accept(TokenType.LPAREN);
  419.         actualParameters();
  420.         ActualParameterNode actualParameters = (ActualParameterNode) currentNode;
  421.         accept(TokenType.RPAREN);
  422.         currentNode = new PrintStatementNode(token, actualParameters);
  423.     }
  424.    
  425.     void readStatement() {
  426.         Token token = currentToken;
  427.         List<VariableNode> variables = new ArrayList<>();
  428.         accept(TokenType.READ);
  429.         accept(TokenType.LPAREN);
  430.         while (currentToken.getTokenType() == TokenType.IDENTIFIER) {
  431.             variable();
  432.             variables.add((VariableNode) currentNode);
  433.         }
  434.         accept(TokenType.RPAREN);
  435.         currentNode = new ReadStatementNode(token, variables);
  436.     }
  437.    
  438.     void assignable() {
  439.         if (TokenType.isFactorTerminal(currentToken.getTokenType())) {
  440.             expression();
  441.         } else if (TokenType.isPrimitiveType(currentToken.getTokenType())) {
  442.             arrayInitialization();
  443.         } else if (TokenType.CHAR_LITERAL == currentToken.getTokenType()) {
  444.             characterLiteral();
  445.         } else {
  446.             stringLiteral();
  447.         }
  448.     }
  449.    
  450.     void characterLiteral() {
  451.         currentNode = new CharacterLiteralNode(currentToken);
  452.         accept(TokenType.CHAR_LITERAL);
  453.     }
  454.    
  455.     void stringLiteral() {
  456.         currentNode = new StringLiteralNode(currentToken);
  457.         accept(TokenType.STRING_LITERAL);
  458.     }
  459.    
  460.     void arrayLength() {
  461.         Token token = currentToken;
  462.         accept(TokenType.LENGTH);
  463.         accept(TokenType.LPAREN);
  464.         variable();
  465.         accept(TokenType.RPAREN);
  466.         currentNode = new ArrayLengthNode(token, (VariableNode) currentNode);
  467.     }
  468.    
  469.     public static void main(String[] args) throws IOException {
  470.         Lexer<TokenType> lexer = new LexerImpl(new SourceImpl("resources/Fib.txt"));
  471.         Parser<TokenType, AST> parser = new ParserImpl(lexer);
  472.         System.out.println(CompilerTestHelper.getASTasString(parser));
  473.     }
  474. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement