public SymbolTuple(NonTerminalSymbol target, TerminalSymbol terminalSymbol, NonTerminalSymbol nonTerminalSymbol) { if (target == null) { throw new ArgumentNullException(nameof(target)); } Target = target; NonTerminalSymbol = nonTerminalSymbol; TerminalSymbol = terminalSymbol; }
private SymbolTuple GetSymbolTuple(GrammarType grammarType, Chain chain, NonTerminalSymbol ruleTarget, NonTerminalSymbol finalTarget = null) { int state = 0; Symbol otherSymbol = null; NonTerminalSymbol nonTerminalSymbol = null; TerminalSymbol terminalSymbol = null; foreach (Symbol symbol in Enumerate(chain, grammarType)) { switch (state) { case 0: otherSymbol = symbol; state = 1; break; case 1: nonTerminalSymbol = otherSymbol.As <NonTerminalSymbol>(); if (nonTerminalSymbol == null) { throw new InvalidOperationException("Expected non terminal symbol."); } terminalSymbol = symbol.As <TerminalSymbol>(); if (terminalSymbol == null) { throw new InvalidOperationException("Expected terminal symbol."); } state = 2; break; default: throw new InvalidOperationException("Expected 2 or less symbols."); } } switch (state) { case 0: if (ruleTarget != Target && finalTarget != null) { throw new InvalidOperationException("Expected that rule target equals to grammar target."); } return(new SymbolTuple(ruleTarget, null, null)); case 1: nonTerminalSymbol = finalTarget != null ? finalTarget : otherSymbol.As <NonTerminalSymbol>(); terminalSymbol = otherSymbol.As <TerminalSymbol>(); if (terminalSymbol == null && nonTerminalSymbol == null) { throw new InvalidOperationException(string.Format("The symbol type is not supported symbol type: {0}.", otherSymbol)); } if (finalTarget != null && terminalSymbol == null) { throw new InvalidOperationException("One symbol chain must contain terminal symbol."); } goto case 2; case 2: default: return(new SymbolTuple(ruleTarget, terminalSymbol, nonTerminalSymbol)); } }