예제 #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

            TreeList <SyntaxAnalizer.ExpressionNode> tree         = new TreeList <SyntaxAnalizer.ExpressionNode>(null);
            TreeList <SyntaxAnalizer.ExpressionNode> currentBlock = tree;
            int             lineNumber = 0;
            SyntaxAnalizer  sa         = new SyntaxAnalizer();
            LexicalAnalizer la         = new LexicalAnalizer();
            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);
                }

                SyntaxAnalizer.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 SyntaxAnalizer.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 SyntaxAnalizer.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 SyntaxAnalizer.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 TreeList <SyntaxAnalizer.ExpressionNode>(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);
                }
            }

            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);
        }
예제 #2
0
 public TreeList(TreeList <T> parent)
 {
     Parent = parent;
 }