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; }
internal IIntermediateClassMethodMember GetProjectionPredictMethod(PredictionTreeDFAdapter adapter) { return(this.predictMethods[adapter]); }