From 17e2f0e9e3568104c4d3314f5dee3afbaaca9810 Mon Sep 17 00:00:00 2001 From: Clemens-Dautermann Date: Sun, 23 Aug 2020 18:30:00 +0200 Subject: [PATCH] comments for parser --- .../.idea/.idea.Compiler/.idea/workspace.xml | 114 ++++++++---------- Compiler/Parser/Parser.cs | 48 +++++++- grammar | 2 +- 3 files changed, 91 insertions(+), 73 deletions(-) diff --git a/Compiler/.idea/.idea.Compiler/.idea/workspace.xml b/Compiler/.idea/.idea.Compiler/.idea/workspace.xml index 8be7039..f600010 100644 --- a/Compiler/.idea/.idea.Compiler/.idea/workspace.xml +++ b/Compiler/.idea/.idea.Compiler/.idea/workspace.xml @@ -20,34 +20,9 @@ - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Compiler/Parser/Parser.cs b/Compiler/Parser/Parser.cs index 8daeecf..636308a 100644 --- a/Compiler/Parser/Parser.cs +++ b/Compiler/Parser/Parser.cs @@ -15,6 +15,7 @@ namespace Compiler.Parser _tokenList = tokenList; } + //A method to check the first token in _tokenList and remove it or raise accoarding error private void CheckFirstTokenAndRemove(TokenType expected) { if (_tokenList.Count == 0) @@ -30,9 +31,13 @@ namespace Compiler.Parser _tokenList.RemoveAt(0); } + //The main RDP function public Node Parse(NodeType nodeType) { + //declare node to be returned Node n; + + //switch over the nodeType to check in which part of the parser we are switch (nodeType) { case NodeType.ProgramNode: @@ -110,43 +115,57 @@ namespace Compiler.Parser throw new MissingTokenException(TokenType.IntegerLiteralToken); } + //an expression always has a first term + //this first term is parsed here Node firstTerm = Parse(NodeType.TermNode); n = firstTerm; + //get next token Token expressionToken = _tokenList[0]; + //if the next token is a + or a - it must be a binary operator because we are in an expression + //that means that this is not a plain constant but a BinaryOperator node while (expressionToken.TokenType == TokenType.AdditionToken || expressionToken.TokenType == TokenType.NegationToken) { + //remove the - or + token _tokenList.RemoveAt(0); switch (expressionToken.TokenType) { + //1. create a BinOp Node + //2. Add the first term as a child + //3. Parse the rest as an expression and add it as the second term case TokenType.AdditionToken: n = new BinaryOperatorNode(OperatorType.Addition); n.Children.Add(firstTerm); - n.Children.Add(Parse(NodeType.TermNode)); + n.Children.Add(Parse(NodeType.ExpressionNode)); break; case TokenType.NegationToken: n = new BinaryOperatorNode(OperatorType.Subtraction); n.Children.Add(firstTerm); - n.Children.Add(Parse(NodeType.TermNode)); + n.Children.Add(Parse(NodeType.ExpressionNode)); break; default: + //this should never happen because the while loop checks for token types, that are + //handled by case statements above only throw new Exception("WeirdException"); } + //if there are still tokens left over pop one off if (_tokenList.Count > 0) { expressionToken = _tokenList[0]; } else { + //there must be tokens left because we are in an expression. throw new MissingTokenException(TokenType.IntegerLiteralToken); } } break; + //the case for term node is almost the same as the one for expression node case NodeType.TermNode: @@ -155,11 +174,13 @@ namespace Compiler.Parser throw new MissingTokenException(TokenType.IntegerLiteralToken); } + //parse first factor Node firstFactor = Parse(NodeType.FactorNode); n = firstFactor; Token termToken = _tokenList[0]; + //parse second factor if it exists while (termToken.TokenType == TokenType.MultiplicationToken || termToken.TokenType == TokenType.DivisionToken) { @@ -169,13 +190,13 @@ namespace Compiler.Parser case TokenType.MultiplicationToken: n = new BinaryOperatorNode(OperatorType.Multiplication); n.Children.Add(firstFactor); - n.Children.Add(Parse(NodeType.FactorNode)); + n.Children.Add(Parse(NodeType.TermNode)); break; case TokenType.DivisionToken: n = new BinaryOperatorNode(OperatorType.Division); n.Children.Add(firstFactor); - n.Children.Add(Parse(NodeType.FactorNode)); + n.Children.Add(Parse(NodeType.TermNode)); break; default: throw new Exception("WeirdException"); @@ -193,6 +214,7 @@ namespace Compiler.Parser break; + case NodeType.FactorNode: if (_tokenList.Count == 0) { @@ -201,20 +223,31 @@ namespace Compiler.Parser Token factorToken = _tokenList[0]; + //switch over possible next tokens. There are three possible options + switch (factorToken.TokenType) { + //first option: + //a parenthesised expression follows. case TokenType.OpenParenthesisToken: + //check and remove openParenthesis (it has already been checked in the case, so removal would be enough) CheckFirstTokenAndRemove(TokenType.OpenParenthesisToken); + //parse the things inside as an expression n = Parse(NodeType.ExpressionNode); + //check if close parenthesis is supplied CheckFirstTokenAndRemove(TokenType.CloseParenthesisToken); break; + //second option: + //this is a unary operator expression case TokenType.NegationToken: case TokenType.BitwiseComplementToken: case TokenType.LogicalNegationToken: + //just parse this as a unary operator node n = Parse(NodeType.UnaryOperatorNode); - n.Children.Add(Parse(NodeType.FactorNode)); break; + //this is an integer literal. case TokenType.IntegerLiteralToken: + //parse it as a constant n = Parse(NodeType.ConstantNode); break; default: @@ -224,6 +257,7 @@ namespace Compiler.Parser break; + //code to parse unary operator nodes case NodeType.UnaryOperatorNode: if (_tokenList.Count == 0) { @@ -231,9 +265,11 @@ namespace Compiler.Parser } else { + //get operator Token unaryOperator = _tokenList[0]; _tokenList.RemoveAt(0); + //switch over three different operators and parse the rest as an expression switch (unaryOperator.TokenType) { case TokenType.BitwiseComplementToken: @@ -256,6 +292,7 @@ namespace Compiler.Parser break; + //parse constant nodes case NodeType.ConstantNode: if (_tokenList.Count == 0) @@ -276,6 +313,7 @@ namespace Compiler.Parser break; } + //default case if the supplied NodeType is unknown default: throw new Exception("Unknown Node Type " + nodeType); } diff --git a/grammar b/grammar index 7d98202..a103f64 100644 --- a/grammar +++ b/grammar @@ -7,4 +7,4 @@ ::= "!" | "~" | "-" ------------ -6+5+2*(3-2)+9 \ No newline at end of file +6+5+2*(3-2)+~9 \ No newline at end of file