Ejemplo n.º 1
0
        public void Parse()
        {
            int cnt_terminal = 0;

            string numCurrLine = "";
            string terminal    = "";
            bool   endStream   = false;

            Stack stack     = new Stack(50);
            Stack stack_AST = new Stack(50);


            LALR_Tables.InitStack(stack);
            LALR_Tables.InitStack(stack_AST);

            int q_next  = -1;
            int q_state = 0;           //state on top of stack

            int    a_input       = -1; //input token (terminal)
            object tokenTerminal = null;

            int    A_input          = -1; // input nonterminal for r-REDUCTION
            object objectProduction = null;

            int ACTION = -2;  //ACTIONS:  -2-ERROR, -1-MOVE, 0-ACCEPT, r-REDUCTION(r>0)
            int rule   = 0;



            bool b_get_CurrentLine = true;

            while (!endStream)
            {
                //1)
                //get <numCurrLine> ==> a_input
                if (b_get_CurrentLine)
                {
                    lock (((ICollection)this.terminalTokenStringQueue).SyncRoot) //lineQueueSync.SyncRoot obSync
                    {
                        cnt_terminal = this.terminalTokenStringQueue.Count;
                        if (this.terminalTokenStringQueue.Count == 0)
                        {
                            Thread.Sleep(0);
                            continue;
                        }
                        //cnt>0
                        numCurrLine = this.terminalTokenStringQueue.Dequeue();
                    }//lock

                    //numCurrLine -> a_input
                    a_input = getInputTerminal(numCurrLine);
                    //(a_input == 0) ==> @ is for Empty String ==  (endStream = true;)
                    //(a_input < 0) ==> no terminal, ERROR
                    //1 <= a_input <= 20==LALR_Tables.NamesTA.GetLength(0) ==> terminal
                }


                if (a_input < 0)
                {
                    ACTION = -2; //-2-ERROR
                }
                else//a_input == 0
                {
                    ACTION = LALR_Tables.AT_LALR_CANONICAL[q_state, a_input];
                }

                //<stack|q_state, a_input.terminalTokenStringQueue,strWriter.> - current configuration
                switch (ACTION)
                {
                case -2:     //-2-ERROR
                    countERRORS++;

                    this.strWriter.WriteLine("*** ACTION = -2-ERROR (see stack)");
                    this.strWriter.WriteLine("*** q_state ={0}, a_input ={1}", q_state, a_input);
                    this.strWriter.WriteLine("*** {0}", numCurrLine);
                    SkipInputTerminals();
                    endStream = true;
                    continue;
                //break;

                case -1:     //-1-MOVE

                    stack.Push(a_input);
                    tokenTerminal = new Terminal(a_input, numCurrLine);
                    stack_AST.Push(tokenTerminal);

                    q_state = LALR_Tables.TGO_LALR[q_state, a_input];
                    stack.Push(q_state);
                    stack_AST.Push(q_state);

                    //endStream == false
                    b_get_CurrentLine = true; //after -1-MOVE
                    continue;                 //!!! get next <numCurrLine> from <terminalTokenStringQueue>

                //break;
                case 0:     //0-ACCEPT
                    ////========objectProduction is Root of AST=============
                    //stack ==(q0,L,q_state)
                    stack_AST.Pop();                                                        //q_state
                    objectProduction = new Production(0, new object[] { stack_AST.Pop() }); //0: <> = L

                    this.strWriter.WriteLine("{0}: {1}", 0, LALR_Tables.Grammar_Prod[0]);
                    endStream = true;
                    continue;

                //break;
                default:
                {
                    //ACTION = r-REDUCTION(r>0)
                    rule = ACTION;

                    //A_input-1000 == nonterminal index in the array NamesNA
                    A_input = doReductions(stack, rule, stack_AST, out objectProduction);         //Apply the production rule: A = alpha

                    if (A_input < 1001)
                    {
                        //the production rule==ACTION was not applyed to <stack>
                        countERRORS++;

                        //ERRORS: -3,-2,-1, 0, ... ,1000
                        //<stack> was not changed:<alpha> was not poped up
                        //Error Configuration before rule==ACTION not applying to <stack>
                        this.strWriter.WriteLine("*** ERROR (see stack): not applying to <stack>\n? {0}: {1}", rule, LALR_Tables.Grammar_Prod[rule]);
                        SkipInputTerminals();

                        endStream = true;
                        continue;
                        //break;
                    }

                    //the production rule==ACTION was applyed to <stack>
                    //<stack> was  changed: <alpha> was poped up

                    q_state = (int)stack.Peek();
                    q_next  = LALR_Tables.NGO_LALR[q_state, A_input - 1000];        //A_input-1000==nonterminal index in the array NamesNA
                    if (q_next == 1)
                    {
                        countERRORS++;
                        //error state q_next == 1
                        //<stack> was changed
                        //Error Configuration after rule==ACTION applying to <stack>
                        this.strWriter.WriteLine("*** ERROR (q_next == 1, see stack): after applying to <stack>\n? {0}: {1}", rule, LALR_Tables.Grammar_Prod[rule]);
                        SkipInputTerminals();
                        endStream = true;
                        continue;
                        //break;
                    }

                    stack.Push(A_input);
                    stack_AST.Push(objectProduction);

                    stack.Push(q_next);
                    stack_AST.Push(q_next);

                    q_state = q_next;

                    //<stack> was changed
                    //a_input not changed
                    //Next Configuration is ready :
                    //(q_state,a_input)

                    //!!!not get next <numCurrLine> from <terminalTokenStringQueue> as "a_input" not changed
                    //CONTINUE PARSING with new "q_state" and old "a_input"
                    //endStream == false

                    this.strWriter.WriteLine("{0}: {1}", rule, LALR_Tables.Grammar_Prod[rule]);

                    b_get_CurrentLine = false;
                    continue;

                    //break;
                }
                } //switch (ACTION)
            }     //while (!endStream)
            ////========objectProduction is Root of AST=============
            //(countERRORS == 0) ==> objectProduction is Root of AST

            if (countERRORS == 0)
            {
                RootAST = objectProduction;
            }
            else
            {
                RootAST = null;
                this.strWriter.WriteLine("*** countERRORS :{0}", countERRORS);
            }

            this.strWriter.WriteLine("#");
        }//Parse
Ejemplo n.º 2
0
        public void methodLexem()
        {
            int cnt_tokenStringQueue = 0;

            string numCurrLine = "";
            string terminal    = "";
            bool   endStream   = false;
            bool   bEnqueue    = false;

            while (!endStream)
            {
                //1)
                lock (((ICollection)this.tokenStringQueue).SyncRoot) //lineQueueSync.SyncRoot obSync
                {
                    cnt_tokenStringQueue = this.tokenStringQueue.Count;
                    if (this.tokenStringQueue.Count == 0)
                    {
                        Thread.Sleep(0);
                        continue; //==> numCurrLine is not gotten and endStream==false,so try again to get it!
                    }
                    else //cnt_tokenStringQueue > 0
                    {
                        numCurrLine = this.tokenStringQueue.Dequeue();
                    }
                }//lock

                //2)
                if (numCurrLine[0] == '#')
                {
                    //Program.strWriter.WriteLine(numCurrLine);
                    ////?Program.strWriter.WriteLine(string.Format("{0}{1}", numCurrLine + "//+", cnt_tokenStringQueue));
                    terminal = string.Format("{0} //+{1}", numCurrLine, cnt_tokenStringQueue);

                    //Program.strWriter.WriteLine(terminal);
                    //
                    streamWriter.WriteLine(terminal);
                    //
                    endStream = true;
                    ////?continue;
                }
                else
                {
                    if (LALR_Tables.IsCommNoTail(numCurrLine))
                    {
                        continue;
                    }
                    if (LALR_Tables.IsTailDelim(numCurrLine))
                    {
                        continue;
                    }
                    if (LALR_Tables.IsRegular(numCurrLine))
                    {
                        terminal = LALR_Tables.NamesTA[16];
                    }
                    else if (LALR_Tables.IsAlphabet(numCurrLine))
                    {
                        terminal = LALR_Tables.NamesTA[1];
                    }
                    else if (LALR_Tables.IsExpression(numCurrLine))
                    {
                        terminal = LALR_Tables.NamesTA[6];
                    }
                    else if (LALR_Tables.IsIdentifier(numCurrLine))
                    {
                        terminal = LALR_Tables.NamesTA[9];
                    }
                    else if (LALR_Tables.IsChar(numCurrLine))
                    {
                        terminal = LALR_Tables.NamesTA[3];
                    }
                    else if (LALR_Tables.IsSTR(numCurrLine))
                    {
                        terminal = LALR_Tables.NamesTA[20];
                    }
                    else if (LALR_Tables.IsOp(numCurrLine))
                    {
                        terminal = LALR_Tables.NamesTA[LALR_Tables.OpTerminal(numCurrLine)];
                    }
                    else
                    {
                        terminal = "qwst";
                    }

                    ////?Program.strWriter.WriteLine(string.Format("{0}{1}{2}", terminal.PadLeft(4, ' ').PadRight(5, ' '), numCurrLine + "//+", cnt_tokenStringQueue));
                    //terminal=string.Format("{0}{1}{2}", terminal.PadLeft(4, ' ').PadRight(5, ' '), numCurrLine+ "//+", cnt_tokenStringQueue);
                    terminal = string.Format("{0}{1}", terminal.PadLeft(4, ' ').PadRight(5, ' '), numCurrLine);//+ "//+", cnt_tokenStringQueue);

                    //Program.strWriter.WriteLine(terminal);
                    //
                    streamWriter.WriteLine(terminal);
                    //

                    //terminal = string.Format("{0} //+{1}", terminal, cnt_tokenStringQueue);
                }

                //3)endStream ==? and terminal are ready!!!

                bEnqueue = false;
                do
                {
                    lock (((ICollection)this.terminalTokenStringQueue).SyncRoot) //lineQueueSync.SyncRoot obSync
                    {
                        if (this.terminalTokenStringQueue.Count < Program.len_terminalTokenStringQueue)
                        {
                            this.terminalTokenStringQueue.Enqueue(terminal);
                            bEnqueue = true;
                        }
                        else
                        {
                            Thread.Sleep(0);
                            continue;//do{...}while (!bEnqueue);
                        }
                    }
                } while (!bEnqueue);
            } //while (!endStream)
            streamWriter.Close();
        }     //Lexem