public void Build(ParserCompiler compiler, ParserBuilder parserBuilder, IIntermediateCliManager identityManager) { /* * * After much of the static analysis has been completed on the grammar, it's now time to generate the parser's full state transition detail. * */ BuildGetValidSyntaxCore(compiler, parserBuilder, identityManager); }
public void Build2(ParserCompiler compiler, ParserBuilder parserBuilder, IIntermediateCliManager identityManager) { BuildCullAmbiguitiesCore(compiler, parserBuilder, identityManager); BuildGetValidSyntax(compiler, parserBuilder, identityManager); BuildDebuggerDisplayForSymbols(compiler, parserBuilder, identityManager); BuildVisitorModel(compiler, identityManager); BuildCullAmbiguities(compiler, parserBuilder, identityManager); }
private void BuildGetValidSyntaxCore(ParserCompiler compiler, ParserBuilder parserBuilder, IIntermediateCliManager identityManager) { var targetClassPartial = parserBuilder.ParserClass.Parts.Add(); this._getValidSyntaxMethodImpl = targetClassPartial.Methods.Add(new TypedName("GetValidSyntax", compiler.LexicalSymbolModel.ValidSymbols)); this._getValidSyntaxMethod = parserBuilder.ParserInterface.Methods.Add(new TypedName("GetValidSyntax", compiler.LexicalSymbolModel.ValidSymbols)); this._getValidSyntaxMethodInternalImpl = targetClassPartial.Methods.Add( new TypedName("GetValidSyntaxInternal", compiler.LexicalSymbolModel.ValidSymbols), new TypedNameSeries( new TypedName("state", RuntimeCoreType.Int32, identityManager), new TypedName("ruleContext", compiler.RuleSymbolBuilder.ILanguageRuleSymbol), new TypedName("initialPass", RuntimeCoreType.Boolean, identityManager))); }
private void BuildCullAmbiguitiesCore(ParserCompiler compiler, ParserBuilder parserBuilder, IIntermediateCliManager identityManager) { bool lexicallyAmbiguousModel = compiler._GrammarSymbols.AmbiguousSymbols.Count() > 0; if (!lexicallyAmbiguousModel) { return; } this._cullAmbiguities = this._getValidSyntaxMethodInternalImpl .Parent .Methods .Add( new TypedName("CullAmbiguitiesFrom", compiler.LexicalSymbolModel.ValidSymbols), new TypedNameSeries( new TypedName("unambiguousSource", compiler.LexicalSymbolModel.ValidSymbols))); var allAmbiguities = compiler.LexicalSymbolModel.GenerateSymbolstoreVariation(new GrammarVocabulary(compiler.GrammarSymbols, compiler._GrammarSymbols.AmbiguousSymbols.ToArray()), "AllAmbiguities", string.Format("Returns a @s:{0}; value that represents all ambiguous identities.", compiler.LexicalSymbolModel.ValidSymbols.Name)); allAmbiguities.Name = "AllAmbiguities"; this._AllAmbiguitiesField = allAmbiguities; _cullAmbiguities.AccessLevel = AccessLevelModifiers.Public; }
private void BuildCullAmbiguities(ParserCompiler compiler, ParserBuilder parserBuilder, IIntermediateCliManager identityManager) { bool lexicallyAmbiguousModel = compiler._GrammarSymbols.AmbiguousSymbols.Count() > 0; if (!lexicallyAmbiguousModel) { return; } var runningAmbiguities = this._cullAmbiguities.Locals.Add( new TypedName("runningAmbiguities", compiler.LexicalSymbolModel.ValidSymbols), new DefaultValueExpression(compiler.LexicalSymbolModel.ValidSymbols)); var resultAmbiguities = this._cullAmbiguities.Locals.Add( new TypedName("resultAmbiguities", compiler.LexicalSymbolModel.ValidSymbols), new DefaultValueExpression(compiler.LexicalSymbolModel.ValidSymbols)); var unambiguousSource = this._cullAmbiguities.Parameters["unambiguousSource"]; this._cullAmbiguities.Comment("Remove the ambiguities that are currently present, a larger multiple-symbol ambiguity may trump what was there due to the follow-union."); this._cullAmbiguities.Assign((IMemberReferenceExpression)unambiguousSource.GetReference(), AssignmentOperation.BitwiseExclusiveOrAssign, unambiguousSource.GetReference().BitwiseAnd(_AllAmbiguitiesField.GetReference())); bool first = true; foreach (var ambiguity in compiler._GrammarSymbols.AmbiguousSymbols) { var ambiguityDetail = compiler.AmbiguityDetail[ambiguity]; IBlockStatementParent target = this._cullAmbiguities; if (first) { first = false; } else { target = target.If(runningAmbiguities.GetReference().BitwiseAnd(ambiguityDetail.AmbiguityKeyReference.GetReference()).InequalTo(ambiguityDetail.AmbiguityKeyReference.GetReference())); } var assignmentCheck = target.If(unambiguousSource.BitwiseAnd(ambiguityDetail.AmbiguityKeyReference).EqualTo(ambiguityDetail.AmbiguityKeyReference)); assignmentCheck.Assign(runningAmbiguities.GetReference(), AssignmentOperation.BitwiseOrAssign, ambiguityDetail.AmbiguityKeyReference.GetReference()); assignmentCheck.Assign(resultAmbiguities.GetReference(), AssignmentOperation.BitwiseOrAssign, ambiguityDetail.AmbiguityReference.GetReference()); } _cullAmbiguities.Return(resultAmbiguities.GetReference()); }
private void BuildGetValidSyntax(ParserCompiler compiler, ParserBuilder parserBuilder, IIntermediateCliManager identityManager) { bool lexicallyAmbiguousModel = compiler._GrammarSymbols.AmbiguousSymbols.Count() > 0; var advanceAdapters = compiler .AdvanceMachines.Values .Select(k => k.All) .DefaultIfEmpty().Aggregate( (a, b) => a.Concat(b)); if (advanceAdapters == null) { advanceAdapters = new PredictionTreeDFAdapter[0]; } var adapters = compiler.FollowAdapters.Select(k => k.Value.AssociatedState).Concat(compiler.AllRuleAdapters.Select(k => k.Value.AssociatedState)).Concat(advanceAdapters.DefaultIfEmpty().Where(k => k != null).Select(k => k.AssociatedState)).Distinct().OrderBy(k => k.StateValue).ToArray(); var distinctStateValues = adapters.Select(k => k.StateValue).Distinct().ToArray(); var stateSymbolStoreEntry = (from state in adapters /* Since the other adapters are state-machines derived from the projection of a given state of a rule, normal adapters (derived from non-expanded lookahead) must be aggregated */ join normalAdapter in compiler.AllRuleAdapters on state equals normalAdapter.Value.AssociatedState into normalVariantSet from normalAdapter in normalVariantSet.DefaultIfEmpty() let fc = (normalAdapter.Value == null || normalAdapter.Value.OutgoingTransitions.Count == 0 || normalAdapter.Value.AssociatedContext.Leaf.LookAhead.Count == 0) ? state.OutTransitions.FullCheck : normalAdapter.Value.AssociatedContext.Leaf.LookAhead.Keys.Aggregate(GrammarVocabulary.UnionAggregateDelegate) group new { State = state, Grammar = fc, GrammarStore = compiler.LexicalSymbolModel.GenerateSymbolstoreVariation(fc) } by new { Grammar = fc, IsEdge = state.IsEdge }).ToDictionary(k => k.Key, v => v.ToArray()); var stateParam = _getValidSyntaxMethodInternalImpl.Parameters["state"]; var ruleContext = _getValidSyntaxMethodInternalImpl.Parameters["ruleContext"]; var initialPass = _getValidSyntaxMethodInternalImpl.Parameters["initialPass"]; if (!lexicallyAmbiguousModel) { _getValidSyntaxMethodInternalImpl.Parameters.Remove(initialPass); initialPass = null; } _getValidSyntaxMethodImpl.AccessLevel = AccessLevelModifiers.Public; var getSyntaxMethodImplInvocation = _getValidSyntaxMethodInternalImpl.GetReference().Invoke(parserBuilder._StateImpl.GetReference(), parserBuilder._CurrentContextImpl.GetReference()); _getValidSyntaxMethodImpl.Return(getSyntaxMethodImplInvocation); if (lexicallyAmbiguousModel) { getSyntaxMethodImplInvocation.Arguments.Add(IntermediateGateway.TrueValue); } ITypedLocalMember pushAmbiguityContext = null; if (lexicallyAmbiguousModel) { pushAmbiguityContext = _getValidSyntaxMethodInternalImpl.Locals.Add( new TypedName("pushAmbiguityContext", RuntimeCoreType.Boolean, identityManager), IntermediateGateway.FalseValue); } ITypedLocalMember validResult = null; if (lexicallyAmbiguousModel) { validResult = _getValidSyntaxMethodInternalImpl.Locals.Add( new TypedName("result", compiler.LexicalSymbolModel.ValidSymbols), this._getValidSyntaxMethodInternalImpl.ReturnType.GetNewExpression()); } var switchStatement = this._getValidSyntaxMethodInternalImpl.Switch(stateParam.GetReference()); foreach (var uniqueGrammarSet in stateSymbolStoreEntry.Keys) { var currentSet = stateSymbolStoreEntry[uniqueGrammarSet]; IExpression[] stateIndices = new IExpression[currentSet.Length]; currentSet = currentSet.OrderBy(k => k.State.StateValue).ToArray(); for (int stateIndex = 0; stateIndex < currentSet.Length; stateIndex++) { stateIndices[stateIndex] = currentSet[stateIndex].State.StateValue.ToPrimitive(); } var currentCase = switchStatement.Case(stateIndices); currentCase.Comment(currentSet[0].Grammar.ToString()); if (uniqueGrammarSet.IsEdge) { //Inject logic to look up in the stack. if (lexicallyAmbiguousModel) { var nullCheck = currentCase.If(ruleContext.InequalTo(IntermediateGateway.NullValue)); nullCheck.Assign(validResult.GetReference(), currentSet[0].GrammarStore.GetReference().BitwiseOr(_getValidSyntaxMethodInternalImpl.GetReference().Invoke(compiler.RuleSymbolBuilder.FollowState.GetReference(ruleContext.GetReference()), compiler.RuleSymbolBuilder.Parent.GetReference(ruleContext.GetReference()), IntermediateGateway.FalseValue))); nullCheck.If(initialPass.GetReference()) .Assign(pushAmbiguityContext.GetReference(), IntermediateGateway.TrueValue); nullCheck.CreateNext(); nullCheck.Next.Assign(validResult.GetReference(), currentSet[0].GrammarStore.GetReference()); } else { var nullCheck = currentCase.If(ruleContext.InequalTo(IntermediateGateway.NullValue)); nullCheck.Return(currentSet[0].GrammarStore.GetReference().BitwiseOr(_getValidSyntaxMethodInternalImpl.GetReference().Invoke(compiler.RuleSymbolBuilder.FollowState.GetReference(ruleContext.GetReference()), compiler.RuleSymbolBuilder.Parent.GetReference(ruleContext.GetReference())))); nullCheck.CreateNext(); nullCheck.Next.Return(currentSet[0].GrammarStore.GetReference()); } } else if (lexicallyAmbiguousModel) { currentCase.Assign(validResult.GetReference(), currentSet[0].GrammarStore.GetReference()); } else { currentCase.Return(currentSet[0].GrammarStore.GetReference()); } } if (lexicallyAmbiguousModel) { this._getValidSyntaxMethodInternalImpl.If(pushAmbiguityContext.GetReference()) .Assign(validResult.GetReference(), AssignmentOperation.BitwiseOrAssign, _cullAmbiguities.GetReference().Invoke(validResult.GetReference())); } if (lexicallyAmbiguousModel) { this._getValidSyntaxMethodInternalImpl.Return(validResult.GetReference()); } else { this._getValidSyntaxMethodInternalImpl.Return(this._getValidSyntaxMethodInternalImpl.ReturnType.GetNewExpression()); } this._getValidSyntaxMethodInternalImpl.AccessLevel = AccessLevelModifiers.Private; }
private void BuildDebuggerDisplayForSymbols(ParserCompiler compiler, ParserBuilder parserBuilder, IIntermediateCliManager identityManager) { var extensionsClass = compiler.RuleSymbolBuilder.ILanguageRuleSymbol.Assembly.DefaultNamespace.Parts.Add().Classes.Add("{0}Extensions", compiler.Source.Options.AssemblyName); extensionsClass.AccessLevel = AccessLevelModifiers.Internal; extensionsClass.SpecialModifier = SpecialClassModifier.Static; this.ExtensionsClass = extensionsClass; var symbolDebuggerDisplay = extensionsClass.Methods.Add( new TypedName("SymbolDebuggerDisplay", RuntimeCoreType.String, identityManager), new TypedNameSeries( new TypedName("symbol", compiler.SymbolStoreBuilder.Identities))); var symbol = symbolDebuggerDisplay.Parameters["symbol"]; var constantEntries = (from s in compiler._GrammarSymbols.SymbolsOfType <IGrammarConstantEntrySymbol>() where !(s.Source is IOilexerGrammarTokenEofEntry) let literalItem = s.Source.Branches[0][0] as ILiteralTokenItem where literalItem != null orderby literalItem.Line, literalItem.Column, literalItem.Value.ToString() select new { LiteralItem = literalItem, Symbol = s }).ToArray(); var constantItems = (from s in compiler._GrammarSymbols.SymbolsOfType <IGrammarConstantItemSymbol>() let literalItem = s.SourceItem orderby literalItem.Line, literalItem.Column, literalItem.Value.ToString() select new { LiteralItem = literalItem, Symbol = s }).ToArray(); var ambiguousItems = (from s in compiler._GrammarSymbols.SymbolsOfType <IGrammarAmbiguousSymbol>() let literalConstantEntry = (IGrammarConstantEntrySymbol)s.FirstOrDefault(aSym => aSym is IGrammarConstantEntrySymbol && constantEntries.Any(ce => ce.Symbol == aSym)) let literalConstantItem = (IGrammarConstantItemSymbol)s.FirstOrDefault(aSym => aSym is IGrammarConstantItemSymbol && constantItems.Any(ci => ci.Symbol == aSym)) where literalConstantEntry != null || literalConstantItem != null let literalItem = literalConstantEntry != null ? literalConstantEntry.Source.Branches[0][0] as ILiteralTokenItem : literalConstantItem.SourceItem orderby literalItem.Line, literalItem.Column, literalItem.Value.ToString() select new { LiteralItem = literalItem, Symbol = s }).ToArray(); var mainSwitch = symbolDebuggerDisplay.Switch(symbol.GetReference()); //compiler.TokenSymbolDetail foreach (var constantEntry in constantEntries) { var symbolDet = compiler.TokenSymbolDetail[constantEntry.Symbol]; var currentCase = mainSwitch.Case(symbolDet.Identity.GetReference()); var fN = symbolDet.Symbol.Source.FileName; if (fN.ToLower().StartsWith(compiler.Source.RelativeRoot)) { currentCase.Comment(string.Format("In .{0} on line {1}, column {2}", fN.Substring(compiler.Source.RelativeRoot.Length), constantEntry.LiteralItem.Line, constantEntry.LiteralItem.Column)); } else { currentCase.Comment(string.Format("In {0} on line {1}, column {2}", fN, constantEntry.LiteralItem.Line, constantEntry.LiteralItem.Column)); } currentCase.Return(constantEntry.LiteralItem.Value.ToString().ToPrimitive()); } foreach (var constantItem in constantItems) { var symbolDet = compiler.TokenSymbolDetail[constantItem.Symbol]; var currentCase = mainSwitch.Case(symbolDet.Identity.GetReference()); var fN = symbolDet.Symbol.Source.FileName; if (fN.ToLower().StartsWith(compiler.Source.RelativeRoot)) { currentCase.Comment(string.Format("In .{0} on line {1}, column {2}", fN.Substring(compiler.Source.RelativeRoot.Length), constantItem.LiteralItem.Line, constantItem.LiteralItem.Column)); } else { currentCase.Comment(string.Format("In {0} on line {1}, column {2}", fN, constantItem.LiteralItem.Line, constantItem.LiteralItem.Column)); } currentCase.Return(constantItem.LiteralItem.Value.ToString().ToPrimitive()); } foreach (var ambiguousItem in ambiguousItems) { var identityField = compiler.LexicalSymbolModel.GetIdentitySymbolField(ambiguousItem.Symbol); var currentCase = mainSwitch.Case(identityField.GetReference()); StringBuilder ambiguityBuilder = new StringBuilder(); ambiguityBuilder.Append("Ambiguity {"); bool first = true; foreach (var ambigSymbol in ambiguousItem.Symbol) { if (first) { first = false; } else { ambiguityBuilder.Append(", "); } ambiguityBuilder.Append(ambigSymbol.ElementName); } ambiguityBuilder.Append("} :"); ambiguityBuilder.Append(ambiguousItem.LiteralItem.Value.ToString().ToPrimitive()); currentCase.Return(ambiguityBuilder.ToString().ToPrimitive()); } mainSwitch.Case(true).Return(symbol.GetReference().GetMethod("ToString").Invoke()); this.SymbolDebuggerDisplay = symbolDebuggerDisplay; symbolDebuggerDisplay.AccessLevel = AccessLevelModifiers.Public; compiler.SymbolStoreBuilder.Identities.Metadata.Add(new MetadatumDefinitionParameterValueCollection(identityManager.ObtainTypeReference(typeof(DebuggerDisplayAttribute))) { string.Format("{{{0}.{1}.{2}(this),nq}}", extensionsClass.NamespaceName, extensionsClass.Name, symbolDebuggerDisplay.Name) }); compiler.FixedTokenBaseBuilder.LanguageFixedToken.Metadata.Add(new MetadatumDefinitionParameterValueCollection(identityManager.ObtainTypeReference(typeof(DebuggerDisplayAttribute))) { string.Format("{{{0}.{1}.{2}(Identity),nq}}", extensionsClass.NamespaceName, extensionsClass.Name, symbolDebuggerDisplay.Name) }); compiler.VariableTokenBaseBuilder.LanguageVariableToken.Metadata.Add(new MetadatumDefinitionParameterValueCollection(identityManager.ObtainTypeReference(typeof(DebuggerDisplayAttribute))) { "{Value,nq}" }); compiler.RootRuleBuilder.LanguageRuleRoot.Metadata.Add(new MetadatumDefinitionParameterValueCollection(identityManager.ObtainTypeReference(typeof(DebuggerDisplayAttribute))) { "{Context.Identity,nq}: {Context}" }); }