Example #1
0
        static void DoTheJob(IEnumerable <string> codeLines)
        {
            Dictionary <string, Token> constants = new Dictionary <string, Token>();
            Dictionary <string, Token> variables = new Dictionary <string, Token>();
            Dictionary <string, Token> operators = new Dictionary <string, Token>();
            Dictionary <string, Token> keywords  = new Dictionary <string, Token>();

            List <LexicalError> errors = new List <LexicalError>();

            // running lexical analysis

            SemanticTreeList tree                   = new SemanticTreeList(null);
            SemanticTreeList currentBlock           = tree;
            int             lineNumber              = 0;
            SyntaxAnalyzer  sa                      = new SyntaxAnalyzer();
            LexicalAnalyzer la                      = new LexicalAnalyzer();
            int             previousLineIndentation = 0;

            foreach (string line in codeLines)
            {
                Construction construction = la.AnaliseLine(line, lineNumber);
                if (construction.Tokens.Count == 0)
                {
                    lineNumber++;
                    continue;
                }
                for (int i = 0; i < construction.Tokens.Count; i++)
                {
                    Token token = construction.Tokens[i];
                    if (token.IsReservedIdToken)
                    {
                        keywords.TryAdd(token.Value, token);
                    }
                    else if (token.IsOperation)
                    {
                        operators.TryAdd(token.Value, token);
                    }
                    else if (token.IsConstant)
                    {
                        constants.TryAdd(token.Value, token);
                    }
                    else if (token.TokenType != TokenTypes.UNKNOWN)
                    {
                        variables.TryAdd(token.Value, token);
                    }
                }

                if (construction.HasErrors)
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine("\t\t ERRORS");
                    Console.ResetColor();
                    foreach (LexicalError error in construction.Errors)
                    {
                        Console.WriteLine($"line {error.CodeLineNumber + 1} char {error.IndexInCodeLine + 1} :: {error.ErrorType}");
                        Console.WriteLine(error.Description);
                    }
                    Console.Read();
                    Environment.Exit(1);
                }

                ExpressionNode node           = null;
                bool           isElifElseNode = false;
                bool           newBlockToOpen = false;

                //node = sa.Analyse(construction.Tokens, out newBlockToOpen, out isElifElseNode);

                //int indentationDiff = previousLineIndentation - construction.Indentation;

                //if (indentationDiff > 0)
                //{
                //    for (int i = previousLineIndentation-1; i >= construction.Indentation; i--)
                //    {
                //        currentBlock = currentBlock.Parent;
                //        if (currentBlock.Indentation == i)
                //            break;
                //    }
                //    // currentBlock = currentBlock.Parent; // TODO: create parent relationship between BLOCKS to support >1 level nesting
                //    if (node.Operator.IsElif && !currentBlock.Last().Operator.IsIf)
                //    {
                //        throw new SyntaxAnalyzer.SyntaxErrorException(
                //                "elif block not allowed here",
                //                node.Operator.Value,
                //                node.Operator.CodeLineIndex,
                //                node.Operator.CodeLineNumber
                //            );
                //    }
                //    else if (node.Operator.IsElse && !(currentBlock.Last().Operator.IsIf || currentBlock.Last().Operator.IsElif))
                //    {
                //        throw new SyntaxAnalyzer.SyntaxErrorException(
                //                "else block not allowed here",
                //                line,
                //                node.Operator.CodeLineIndex,
                //                node.Operator.CodeLineNumber
                //            );
                //    }
                //}
                //previousLineIndentation = construction.Indentation;
                //lineNumber++;

                //if (newBlockToOpen)
                //{
                //    if ((node.Operator.IsElif || node.Operator.IsElse) && !currentBlock.Last().Operator.IsIf && !currentBlock.Last().Operator.IsElif)
                //    {
                //        throw new SyntaxAnalyzer.SyntaxErrorException(
                //            "lacks IF clause for elif|else block to appear",
                //            node.Operator.Value,
                //            node.Operator.CodeLineIndex,
                //            node.Operator.CodeLineNumber
                //            );
                //    }
                //    currentBlock.Add(node);
                //    currentBlock.Last().Block = new SemanticTreeList(currentBlock);
                //    currentBlock = currentBlock.Last().Block;
                //    currentBlock.Indentation = construction.Indentation;
                //    continue;
                //}

                //currentBlock.Add(node);
            }

            if (errors.Any())
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("\t\t ERRORS");
                Console.ResetColor();
                foreach (LexicalError error in errors)
                {
                    Console.WriteLine($"line {error.CodeLineNumber + 1} char {error.IndexInCodeLine + 1} :: {error.ErrorType}");
                    Console.WriteLine(error.Description);
                }
            }
            // semantic analysis
            Console.WriteLine("SYNTAX TREE:\n");
            PrintSyntaxTree(tree);

            // console tables output block
            Console.WriteLine("\n \t\t CONSTANTS");
            PrintTokensDictionary(constants);

            Console.WriteLine("\n \t\t VARIABLES");
            PrintTokensDictionary(variables);

            Console.WriteLine("\n \t\t KEYWORS");
            PrintTokensDictionary(keywords);

            Console.WriteLine("\n \t\t OPERATORS");
            PrintTokensDictionary(operators);

            SemanticErrorException semanticError = App.DoSemanticCheck();

            if (semanticError != null)
            {
                throw semanticError;
            }

            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine("\n---Interpretation complete---");
            Console.ResetColor();
        }
Example #2
0
        protected ExpressionNode BuildTree(IEnumerable <Token> tokens, ExpressionNode parent = null)
        {
            ExpressionNode root = null;
            ExpressionNode left = null;

            Token token = tokens.FirstOrDefault();

            if (token is null)
            {
                return(null);
            }

            if (token.IsConstant || token.TokenType == Token.TokenTypes.ID || token.TokenType == Token.TokenTypes.BUILT_IN_FUNCTION)
            {
                left = new ExpressionNode()
                {
                    Operator = token,
                    Type     = ExpressionNode.TokensToExpressionTypes.GetOrDefault(token.TokenType, ExpressionNode.ExpressionTypes.UNKNOWN)
                };
                var tt = tokens.ElementAtOrDefault(1)?.TokenType;
                if (tt == TokenTypes.OPENING_ROUND_BRACKET || tt == TokenTypes.OPENING_SQUARE_BRACKET)
                {
                    root = left;
                    left = null;
                    if (tt == TokenTypes.OPENING_SQUARE_BRACKET)
                    {
                        root.Type = ExpressionNode.ExpressionTypes.INDEXER_CALL;
                    }
                    else
                    {
                        root.Type = ExpressionNode.ExpressionTypes.FUNCTION_CALL;
                    }
                    root.Right = BuildTree(tokens.Skip(1));
                }

                //
                else
                {
                    root        = BuildTree(tokens.Skip(1));
                    left.Parent = root;
                }
            }
            else if (token.IsOpeningBracket)
            {
                this.OpenedBracketsLevel++;

                root = BuildTree(tokens.Skip(1));
                if (root != null)
                {
                    root.OperatorPriority++;
                }
            }
            else if (token.IsClosingBracket)
            {
                this.OpenedBracketsLevel--;
                root = BuildTree(tokens.Skip(1));
                if (root != null)
                {
                    root.OperatorPriority--;
                }
            }

            else if (token.IsOperation)
            {
                root = new ExpressionNode()
                {
                    Operator = token,
                    Type     = ExpressionNode.TokensToExpressionTypes.GetOrDefault(token.TokenType, ExpressionNode.ExpressionTypes.UNKNOWN)
                };
                if (token.TokenType == Token.TokenTypes.MULTIPLICATION || token.TokenType == Token.TokenTypes.DIVISION)
                {
                    root.OperatorPriority++;
                }


                root.Right = BuildTree(tokens.Skip(1), root);
            }
            if (root is null)
            {
                if (left is null)
                {
                    return(null);
                }
                left.Parent = parent;
                return(left);
            }
            root.Parent = parent;
            if (left != null)
            {
                root.InsertDeepLeft(left);
            }

            if (root.Right != null && root.Operator.IsOperation && root.Right.Operator.IsOperation && root.OperatorPriority > root.Right.OperatorPriority)
            {
                return(root.LeftRotation());
            }
            return(root);
        }