예제 #1
0
        static void Parse(GrammarSymbol symbol)
        {
            if (!errorEncountered)
            {
                if (symbol is Nonterminal)
                {
                    Nonterminal n = symbol as Nonterminal;

                    /*Console.WriteLine(n.name);
                     * Console.ReadLine();*/

                    int currentPaths = 0;
                    foreach (Transition t in n.transitions)
                    {
                        currentPaths++;
                        //Console.WriteLine("I am {0} paths deep in {1}.", currentPaths, n.name);
                        wrongPath = false;
                        foreach (GrammarSymbol g in t.symbols)
                        {
                            Parse(g);
                            if (wrongPath)
                            {
                                break;
                            }
                        }

                        if (!wrongPath)
                        {
                            break;
                        }
                    }
                }
                else
                {
                    Terminal term = symbol as Terminal;

                    Token t = tz.GetNextToken();
                    if (t.type == TokenType.ERROR)
                    {
                        errorEncountered = true;
                    }
                    else
                    {
                        /*Console.WriteLine("{0} vs {1}", t.type.ToString(), term.matchesToken.type.ToString());
                         * Console.ReadLine();*/

                        if (t.type != term.matchesToken.type)
                        {
                            wrongPath = true;
                        }
                        else
                        {
                            tz.GetNextToken(true);
                        }
                    }
                }
            }
        }
예제 #2
0
 /// <summary>
 /// Создание нового экземпляра инструкции компилятору.
 /// </summary>
 /// <param name="Source">Источник, кто добавил в компилятор запись.</param>
 /// <param name="Helper">Дополнительная информация о результатах парсера.</param>
 public ParserToken(Nonterminal Source, RuleOperator CurrentRule, int Helper = int.MinValue, ulong Id = ulong.MaxValue)
 {
     this.Source      = Source;
     this.CurrentRule = CurrentRule;
     this.Helper      = Helper;
     if (Id != ulong.MaxValue)
     {
         this.Id = Id;
     }
     else
     {
         this.Id = ran.NextULong();
     }
 }
예제 #3
0
 public ParserLang(Nonterminal mainNonterminal)
 => this.mainNonterminal = mainNonterminal ?? throw new ArgumentNullException(nameof(mainNonterminal));
예제 #4
0
        static void Main(string[] args)
        {
            if (args.Length != 1) //Wrong number of command line arguments
            {
                Console.WriteLine("Usage: Parser.exe <name of file>");
            }
            else
            {
                #region GrammarSetup

                //Terminals
                Terminal grammarOperator = new Terminal(new Token(TokenType.OPERATOR));
                Terminal identifier      = new Terminal(new Token(TokenType.IDENTIFIER));
                Terminal integer         = new Terminal(new Token(TokenType.INT));
                Terminal openParen       = new Terminal(new Token(TokenType.OPEN_PAREN));
                Terminal closeParen      = new Terminal(new Token(TokenType.CLOSE_PAREN));
                Terminal begin           = new Terminal(new Token(TokenType.BEGIN));
                Terminal end             = new Terminal(new Token(TokenType.END));
                Terminal read            = new Terminal(new Token(TokenType.READ));
                Terminal write           = new Terminal(new Token(TokenType.WRITE));
                Terminal comma           = new Terminal(new Token(TokenType.COMMA));
                Terminal semicolon       = new Terminal(new Token(TokenType.SEMICOLON));
                Terminal assignment      = new Terminal(new Token(TokenType.ASSIGNMENT));

                //Nonterminals
                Nonterminal expr = new Nonterminal();
                expr.name = "expr";

                Nonterminal ident = new Nonterminal(new Transition(identifier));
                ident.name = "ident";
                Nonterminal op = new Nonterminal(new Transition(grammarOperator));
                op.name = "op";
                Nonterminal factor = new Nonterminal(new Transition(openParen, expr, closeParen), new Transition(integer), new Transition(ident));
                factor.name = "factor";

                Nonterminal expr_tail = new Nonterminal();
                expr_tail.name = "expr_tail";
                expr_tail.AddTransition(new Transition(op, factor, expr_tail));
                expr_tail.AddTransition(new Transition());
                expr.AddTransition(new Transition(factor, expr_tail));
                expr.AddTransition(new Transition());

                Nonterminal expr_list_tail = new Nonterminal();
                expr_list_tail.name = "expr_list_tail";
                expr_list_tail.AddTransition(new Transition(comma, expr, expr_list_tail));
                expr_list_tail.AddTransition(new Transition());
                Nonterminal expr_list = new Nonterminal(new Transition(expr, expr_list_tail));
                expr_list.name = "expr_tail";

                Nonterminal id_list_tail = new Nonterminal();
                id_list_tail.name = "id_list_tail";
                id_list_tail.AddTransition(new Transition(comma, ident, id_list_tail));
                id_list_tail.AddTransition(new Transition());

                Nonterminal id_list = new Nonterminal(new Transition(ident, id_list_tail));
                id_list.name = "id_list";

                Nonterminal stmt = new Nonterminal(new Transition(ident, assignment, expr, semicolon), new Transition(read, openParen, id_list, closeParen, semicolon), new Transition(write, openParen, expr_list, closeParen, semicolon));
                stmt.name = "stmt";

                Nonterminal stmt_list_tail = new Nonterminal();
                stmt_list_tail.name = "stmt_list_tail";
                stmt_list_tail.AddTransition(new Transition(stmt, stmt_list_tail));
                stmt_list_tail.AddTransition(new Transition());
                Nonterminal stmt_list = new Nonterminal(new Transition(stmt, stmt_list_tail));
                stmt_list.name = "stmt_list";

                Nonterminal program = new Nonterminal(new Transition(begin, stmt_list, end));
                program.name = "program";

                #endregion

                tz = new Tokenizer(File.ReadAllText(args[0]));

                Parse(program);

                if (errorEncountered)
                {
                    Console.WriteLine(tz.GetNextToken().name);
                }
                else if (tz.sourceString.Length != 0)
                {
                    switch (tz.GetNextToken().type)
                    {
                    case TokenType.ASSIGNMENT:
                        Console.WriteLine("Error 2: Unexpected assignment at position {0}.", tz.currentPosition);
                        break;

                    case TokenType.BEGIN:
                        Console.WriteLine("Error 3: Unexpected BEGIN at position {0}.", tz.currentPosition);
                        break;

                    case TokenType.CLOSE_PAREN:
                        Console.WriteLine("Error 4: Unexpected ) at position {0}.", tz.currentPosition);
                        break;

                    case TokenType.COMMA:
                        Console.WriteLine("Error 5: Unexpected , at position {0}.", tz.currentPosition);
                        break;

                    case TokenType.IDENTIFIER:
                        Console.WriteLine("Error 6: Unexpected identifier {0} at position {1}.", tz.GetNextToken().name, tz.currentPosition);
                        break;

                    case TokenType.INT:
                        Console.WriteLine("Error 7: Unexpected integer at position {0}.", tz.currentPosition);
                        break;

                    case TokenType.OPEN_PAREN:
                        Console.WriteLine("Error 8: Unexpected ( at position {0}.", tz.currentPosition);
                        break;

                    case TokenType.OPERATOR:
                        Console.WriteLine("Error 9: Unexpected {0} at position {1}.", tz.GetNextToken().name, tz.currentPosition);
                        break;

                    case TokenType.READ:
                        Console.WriteLine("Error 10: Unexpected read at position {0}.", tz.currentPosition);
                        break;

                    case TokenType.SEMICOLON:
                        Console.WriteLine("Error 11: Unexpected ; at position {0}.", tz.currentPosition);
                        break;

                    case TokenType.WRITE:
                        Console.WriteLine("Error 12: Unexpected write at position {0}.", tz.currentPosition);
                        break;
                    }
                }
                else
                {
                    Console.WriteLine("File parsed successfully with no errors.");
                }
            }
        }