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
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