private Core.GrammarElements.Production GetAugmentedProduction(NonTerminal start, GrammarSymbol root, GrammarSymbol endOfStream) { return new Core.GrammarElements.Production(_productionId++, start, new[] { root, endOfStream }); }
private CodeTypeMember ImplementReducerGoto(NonTerminal head) { var result = new CodeMemberMethod() { Name = Constants.ReductionGotoMethodName, ReturnType = new CodeTypeReference(typeof(void)), Attributes = MemberAttributes.Public | MemberAttributes.Final }; result.Parameters.Add(new CodeParameterDeclarationExpression(Constants.StateStackType, Constants.StateStackVarName)); var states = new CodeArgumentReferenceExpression(Constants.StateStackVarName); result.Statements.Add(DeclareVariable(new CodeTypeReference(typeof(int)), "currentState", new CodeMethodInvokeExpression(states, "Peek"))); foreach (var state in _transitionTable.StateMap.States) { var action = _transitionTable[state, head]; if (action.Action == ParserAction.Goto) { var ifState = new CodeConditionStatement(new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression("currentState"), CodeBinaryOperatorType.ValueEquality, new CodePrimitiveExpression(state.StateId))); ifState.TrueStatements.Add(new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(states, "Push"), new CodePrimitiveExpression(action.NextState.StateId))); ifState.TrueStatements.Add(new CodeMethodReturnStatement()); result.Statements.Add(ifState); } } result.Statements.Add(new CodeThrowExceptionStatement(new CodeObjectCreateExpression(typeof(Exception), new CodePrimitiveExpression("Unexpected GOTO operation.")))); return result; }
public Grammar GetGrammar() { string fileContents = File.ReadAllText(_fileName); var tokenStream = Lexer.Run(fileContents); var parser = new Parser(); var parseTree = parser.Parse(tokenStream); var grammarCreator = new GrammarTreeVisitor(); parseTree.AcceptVisitor(grammarCreator); var isValid = ValidateGrammar(grammarCreator.Tokens, grammarCreator.Productions); var terminals = (from symbolName in grammarCreator.Tokens select new Terminal(_symbolId++, symbolName)) .ToDictionary(terminal => terminal.Name); var nonTerminals = grammarCreator.Productions .Select(production => production.ProductionHead) .Distinct() .Select(symbolName => new NonTerminal(_symbolId++, symbolName)) .ToDictionary(nonTerminal => nonTerminal.Name); var productions = new List<Core.GrammarElements.Production>(); foreach (var nonTerminal in nonTerminals.Keys) { foreach (var production in grammarCreator.Productions.Where(x => x.ProductionHead == nonTerminal)) { var tail = new GrammarSymbol[production.ProductionTail.Count]; for (int i = 0; i < tail.Length; i++) { var productionToken = production.ProductionTail[i]; if (terminals.ContainsKey(productionToken)) { tail[i] = terminals[productionToken]; } else if(nonTerminals.ContainsKey(productionToken)) { tail[i] = nonTerminals[productionToken]; } else { throw new Exception("Unknown production head."); } } productions.Add(new Core.GrammarElements.Production(_productionId++, nonTerminals[nonTerminal], tail)); } } var endOfStream = EndOfStream.Instance; terminals.Add(endOfStream.Name, endOfStream); var startAugmentedSymbol = new NonTerminal(_symbolId++, AugmentedStart); nonTerminals.Add(AugmentedStart, startAugmentedSymbol); var root = GetGrammarRoot(productions); var augmentedProduction = GetAugmentedProduction(startAugmentedSymbol, root, endOfStream); productions.Add(augmentedProduction); return new Grammar(productions, terminals.Values.Cast<GrammarSymbol>().Concat(nonTerminals.Values).ToList(), new Item(augmentedProduction)); }
private void AddSymbol(NonTerminal head, IEnumerable<Production> productions) { var nonTermAbstractBase = new CodeTypeDeclaration(head.Name); nonTermAbstractBase.BaseTypes.Add(new CodeTypeReference(Constants.ReductionInterfaceName)); nonTermAbstractBase.TypeAttributes = TypeAttributes.Abstract | TypeAttributes.Public; nonTermAbstractBase.Members.Add(ImplementReducerGoto(head)); var concreteTypes = GetConcreteTypesForProductions(nonTermAbstractBase, productions); _codeNamespace.Types.Add(nonTermAbstractBase); _codeNamespace.Types.AddRange(concreteTypes.ToArray()); }