// BorderIndex = 0 - begin border // BorderIndex = 1 - end border public Token GetBorderToken(int BorderIndex = 0, bool IncludeNoise = false) { Reduction DataReduction = (Reduction)Data; int TokenCount = DataReduction.TokenCount; Token TokenCandidate; for (int Counter = 1; Counter <= TokenCount; Counter++) { if (BorderIndex == 1) { TokenCandidate = (Token)DataReduction.Tokens(TokenCount - Counter); } else { TokenCandidate = (Token)DataReduction.Tokens(Counter - 1); } if (TokenCandidate.Type == SymbolType.Terminal) { if (IncludeNoise && BorderIndex == 1 && TokenCandidate.EndNoise != null) { return(TokenCandidate.EndNoise); } else if (IncludeNoise && BorderIndex == 0 && TokenCandidate.BeginNoise != null) { return(TokenCandidate.BeginNoise); } else { return(TokenCandidate); } } else //if (TokenCandidate.Type == SymbolType.Nonterminal) { if (((Reduction)TokenCandidate.Data).TokenCount > 0) { Token TokenFromBottom = TokenCandidate.GetBorderToken(BorderIndex, IncludeNoise); if (TokenFromBottom != null) { return(TokenFromBottom); } } } } return(null); }
/// <summary> /// This function analyzes a token and either: /// 1. Makes a SINGLE reduction and pushes a complete Reduction object on the _stack /// 2. Accepts the token and shifts /// 3. Errors and places the expected symbol indexes in the Tokens list /// The Token is assumed to be valid and WILL be checked /// If an action is performed that requires controlt to be returned to the user, the function returns true. /// The Message parameter is then set to the type of action. /// </summary> /// <param name="nextToken"></param> /// <returns></returns> private ParseResult ParseLALR(Token nextToken) { ParseResult result = default(ParseResult); LRAction parseAction = _lrStates[_currentLALR][(nextToken.Parent)]; // Work - shift or reduce if ((parseAction != null)) { _haveReduction = false; //Will be set true if a reduction is made //'Debug.WriteLine("Action: " & ParseAction.Text) switch (parseAction.Type) { case LRActionType.Accept: _haveReduction = true; result = ParseResult.Accept; break; case LRActionType.Shift: _currentLALR = parseAction.Value; nextToken.State = (short)_currentLALR; _stack.Push(nextToken); result = ParseResult.Shift; break; case LRActionType.Reduce: //Produce a reduction - remove as many tokens as members in the rule & push a nonterminal token Production prod = _productionTable[parseAction.Value]; //======== Create Reduction Token head; int n; if (TrimReductions && prod.ContainsOneNonTerminal()) { //The current rule only consists of a single nonterminal and can be trimmed from the //parse tree. Usually we create a new Reduction, assign it to the Data property //of Head and push it on the _stack. However, in this case, the Data property of the //Head will be assigned the Data property of the reduced token (i.e. the only one //on the _stack). //In this case, to save code, the value popped of the _stack is changed into the head. head = _stack.Pop(); head.Parent = prod.RuleNonterminal; result = ParseResult.ReduceEliminated; //Build a Reduction } else { _haveReduction = true; var newReduction = new Reduction(prod.Handle.Count); newReduction.ParentRule = prod; for (n = prod.Handle.Count - 1; n >= 0; n += -1) { newReduction[n] = _stack.Pop(); } head = new Token(prod.RuleNonterminal, newReduction); //bool IsFirst; //if (_stack.Count == 0) //{ // IsFirst = true; //} //else //{ // IsFirst = false; //} //newReduction.EndNoise = _lastNoise; result = ParseResult.ReduceNormal; } //========== Goto short index = _stack.Peek().State; //========= If n is -1 here, then we have an Internal Table Error!!!! n = _lrStates[index].IndexOf(prod.RuleNonterminal); if (n != -1) { _currentLALR = _lrStates[index][n].Value; head.State = (short)_currentLALR; _stack.Push(head); } else { result = ParseResult.InternalError; } break; } } else { //=== Syntax Error! Fill Expected Tokens _expectedSymbols.Clear(); //.Count - 1 foreach (LRAction action in _lrStates[_currentLALR]) { switch (action.Symbol.Type) { case SymbolType.Terminal: case SymbolType.End: case SymbolType.GroupStart: case SymbolType.GroupEnd: _expectedSymbols.Add(action.Symbol); break; } } result = ParseResult.SyntaxError; } return(result); }