protected LalrActionWithLalrState(int index, Symbol symbol, LalrState state): base(index, symbol) { if (state == null) { throw new ArgumentNullException("state"); } Debug.Assert(symbol.Owner == state.Owner); this.state = state; }
/// <summary> /// Read LALR state information. /// </summary> private void ReadLalrStates() { int index = ReadInt16Entry(); ReadEmptyEntry(); LalrStateAction[] stateTable = new LalrStateAction[m_entryCount / 4]; for (int i = 0; i < stateTable.Length; i++) { Symbol symbol = m_symbolTable[ReadInt16Entry()]; LalrAction action = (LalrAction)ReadInt16Entry(); int targetIndex = ReadInt16Entry(); ReadEmptyEntry(); stateTable[i] = new LalrStateAction(i, symbol, action, targetIndex); } // Create the transition vector LalrStateAction[] transitionVector = new LalrStateAction[m_symbolTable.Length]; for (int i = 0; i < transitionVector.Length; i++) { transitionVector[i] = null; } for (int i = 0; i < stateTable.Length; i++) { transitionVector[stateTable[i].Symbol.Index] = stateTable[i]; } LalrState lalrState = new LalrState(index, stateTable, transitionVector); m_lalrStateTable[index] = lalrState; }
public LalrStack(LalrState initialState) { if (initialState == null) { throw new ArgumentNullException("initialState"); } items[0] = new KeyValuePair <T, LalrState>(default(T), initialState); }
public void Push(T token, LalrState state) { topIndex++; if ((topIndex + 1) == items.Length) { Array.Resize(ref items, items.Length * 2); } items[topIndex] = new KeyValuePair <T, LalrState>(token, state); }
/// <summary> /// Initializes new instance of Parser class. /// </summary> /// <param name="tokenizer">The tokenizer.</param> /// <param name="trim">if set to <c>true</c> [trim].</param> protected LalrProcessor(ITokenizer <T> tokenizer) { if (tokenizer == null) { throw new ArgumentNullException("tokenizer"); } this.tokenizer = tokenizer; currentState = tokenizer.Grammar.InitialLRState; tokenStack = new LalrStack <T>(currentState); }
/// <summary> /// Creates a new instance of the <c>Parser</c> class. /// </summary> /// <param name="input">String to parse.</param> /// <param name="grammar">Grammar rules.</param> public Parser(string input, Grammar grammar) { m_grammar = grammar; CharReader charReader = new CharReader(input); m_tokenReader = new TokenReader(charReader, grammar); m_currentLalrState = m_grammar.InitialLalrState; Symbol symbol = m_grammar.StartSymbol; Token start = new Token(symbol, (Reduction)null); start.LalrState = m_currentLalrState; m_stack.Push(start); }
private TokenParseResult ParseToken(Token nextToken) { LalrStateAction stateAction = m_currentLalrState.GetActionBySymbolIndex(nextToken.Symbol.Index); m_tokens.Clear(); if (stateAction != null) { //Work - shift or reduce m_haveReduction = false; //Will be set true if a reduction is made switch (stateAction.Action) { case LalrAction.Accept: m_haveReduction = true; return(TokenParseResult.Accept); case LalrAction.Shift: m_currentLalrState = Grammar.LalrStateTable[stateAction.Value]; nextToken.LalrState = m_currentLalrState; m_stack.Push(nextToken); return(TokenParseResult.Shift); case LalrAction.Reduce: //Produce a reduction - remove as many tokens as members in the rule & push a nonterminal token int ruleIndex = stateAction.Value; Rule currentRule = Grammar.RuleTable[ruleIndex]; //======== Create Reduction Token head; TokenParseResult parseResult; if (TrimReductions && currentRule.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 = m_stack.PopToken(); head.Symbol = currentRule.NonTerminal; parseResult = TokenParseResult.ReduceEliminated; } else { //Build a Reduction m_haveReduction = true; Reduction reduction = new Reduction(currentRule); for (int i = 0; i < currentRule.Count; i++) { reduction.InsertToken(0, m_stack.PopToken()); } head = new Token(currentRule.NonTerminal, reduction); parseResult = TokenParseResult.ReduceNormal; } //========== Goto LalrState nextState = m_stack.PeekToken().LalrState; //========= If nextAction is null here, then we have an Internal Table Error!!!! LalrStateAction nextAction = nextState.GetActionBySymbolIndex(currentRule.NonTerminal.Index); if (nextAction != null) { m_currentLalrState = Grammar.LalrStateTable[nextAction.Value]; head.LalrState = m_currentLalrState; m_stack.Push(head); return(parseResult); } else { return(TokenParseResult.InternalError); } } } else { //=== Syntax Error! Fill Expected Tokens for (int i = 0; i < m_currentLalrState.ActionCount; i++) { switch (m_currentLalrState.GetAction(i).Symbol.SymbolType) { case SymbolType.Terminal: case SymbolType.End: Token token = new Token(m_currentLalrState.GetAction(i).Symbol, "", m_tokenReader.LineNumber); m_tokens.Push(token); break; } } } return(TokenParseResult.SyntaxError); }
/// <summary> /// Loads grammar from the binary reader. /// </summary> private void Load(LoadContext context) { string headerString = context.ReadHeaderString(); // Trace.WriteLine(headerString, "Reading header"); Match headerMatch = FileHeader.Match(headerString); if (!headerMatch.Success) { throw new FileLoadException("The File Header is invalid or unsupported: "+headerString); } switch (headerMatch.Groups["version"].Value) { case "1.0": fileVersion = CgtVersion.V1_0; break; case "5.0": fileVersion = CgtVersion.V5_0; break; default: throw new FileLoadException(string.Format("The file format version {0} is not unsupported", headerMatch.Groups["version"].Value)); } while (context.HasMoreData()) { CgtRecordType recordType = context.ReadNextRecord(); /// Trace.WriteLine(recordType, "Reading record"); switch (recordType) { case CgtRecordType.Parameters: ReadHeader(context); break; case CgtRecordType.Property: ReadProperty(context); break; case CgtRecordType.Groups: ReadGroup(context); break; case CgtRecordType.TableCountsEnhanced: ReadTableCounts(context, true); break; case CgtRecordType.TableCounts: ReadTableCounts(context, false); break; case CgtRecordType.Initial: ReadInitialStates(context); break; case CgtRecordType.Symbols: ReadSymbol(context); break; case CgtRecordType.Charsets: ReadCharset(context); break; case CgtRecordType.PackedCharsets: if (fileVersion == CgtVersion.V1_0) { ReadPackedCharset(context); } else { ReadRangeCharset(context); } break; case CgtRecordType.Rules: ReadRule(context); break; case CgtRecordType.DfaStates: ReadDfaState(context); break; case CgtRecordType.LRStates: ReadLRState(context); break; default: throw new FileLoadException("Invalid record type"); } } dfaInitialState = dfaStateTable[context.DfaInitialStateIndex]; startSymbol = symbolTable[context.StartSymbolIndex]; lalrInitialState = lalrStateTable[context.LrInitialState]; FixupGroups(context); }
/// <summary> /// Reads table record counts and initializes tables. /// </summary> /// <param name="context"></param> private void ReadTableCounts(LoadContext context, bool readGroups) { // Initialize tables symbolTable = new Symbol[context.ReadIntegerEntry()]; charSetTable = new DfaCharset[context.ReadIntegerEntry()]; ruleTable = new Rule[context.ReadIntegerEntry()]; for (int i = 0; i < ruleTable.Length; i++) { ruleTable[i] = new Rule(this, i); } dfaStateTable = new DfaState[context.ReadIntegerEntry()]; for (int i = 0; i < dfaStateTable.Length; i++) { dfaStateTable[i] = new DfaState(this, i); } lalrStateTable = new LalrState[context.ReadIntegerEntry()]; for (int i = 0; i < lalrStateTable.Length; i++) { lalrStateTable[i] = new LalrState(this, i); } groupTable = new Group[readGroups ? context.ReadIntegerEntry() : 0]; }
void IParser <T> .PushTokenAndState(T token, LalrState state) { Debug.Assert(state != null); tokenStack.Push(token, state); currentState = state; }