public void AddSymbol(CilSymbolRef token) { if (symbols.Contains(token)) { return; } symbols.Add(token); // Provide new rules from existing meta var newTokens = new[] { token }; foreach (var meta in validMetadata) { var newParseRules = meta.GetProductions(newTokens); foreach (var parseRule in newParseRules) { this.AddProduction(meta, parseRule); } } // Provide new meta (DemandAttribute) if (!token.HasLiteral) { foreach (var meta in MetadataParser.EnumerateAndBind(token.Type)) { this.AddMeta(meta); } } }
internal CilMatcher(Type outcomeType) : this() { var outcome = CilSymbolRef.Create(outcomeType); MainOutcome = outcome; AllOutcomes.Add(outcome); }
public CilProduction(CilSymbolRef outcome, IEnumerable <CilSymbolRef> pattern, CilContextRef context, Pipe <IActionCode> actionBuilder, Precedence precedence = null) { this.Outcome = outcome; this.Pattern = pattern.ToArray(); this.Context = context; this.ActionBuilder = actionBuilder; this.Precedence = precedence; }
public CilSymbol Resolve(CilSymbolRef symbolRef) { if (symbolRef == null) { return(null); } var literalDef = ResolveLiteral(symbolRef.Literal); var tokenTypeDef = ResolveTokenType(symbolRef.Type); if (literalDef != null && tokenTypeDef != null && literalDef != tokenTypeDef) { throw new InvalidOperationException("Unable to resolve conflicting token reference: " + symbolRef); } return(literalDef ?? tokenTypeDef); }
private static CilMatcher CreateImplicitLiteralMatcher(string literal) { var outcome = CilSymbolRef.Create(literal); // Generate implicit scan rule for the keyword var result = new CilMatcher { Context = CilContextRef.None, MainOutcome = outcome, AllOutcomes = { outcome }, Disambiguation = Disambiguation.Exclusive, Pattern = ScanPattern.CreateLiteral(literal), ActionBuilder = code => code .Emit(il => il.Ldnull()) .ReturnFromAction() }; return(result); }
private static SymbolBase GetMatcherOutcomeSymbol( Grammar grammar, ICilSymbolResolver symbolResolver, CilSymbolRef mainOutcome, IEnumerable <CilSymbolRef> allOutcomes) { Symbol main = symbolResolver.GetSymbol(mainOutcome); Symbol[] all = (from outcome in allOutcomes select symbolResolver.GetSymbol(outcome)) .ToArray(); switch (all.Length) { case 0: return(null); case 1: return(main); default: return(new AmbiguousSymbol(main, all)); } }
private CilSymbol Ensure(CilSymbolRef symbolRef) { CilSymbol literalDef = ResolveLiteral(symbolRef.Literal); CilSymbol typeDef = ResolveTokenType(symbolRef.Type); CilSymbol def = MergeDefs(literalDef, typeDef); if (def == null) { def = new CilSymbol(); } else if (symbolRef.Type != null && def.Type != null && def.Type != symbolRef.Type) { throw new InvalidOperationException("Incompatible symbol constraints."); } // Add token to a defintion if (symbolRef.Type != null) { def.Type = symbolRef.Type; } if (symbolRef.HasLiteral) { def.Literals.Add(symbolRef.Literal); } // Update index foreach (var literal in def.Literals) { ref2def[literal] = def; } if (def.Type != null) { ref2def[def.Type] = def; } return(def); }
public CilGrammar(CilGrammarSource source, ILogging logging) { Type definitionType = source.DefinitionType; GlobalContextProvider = new CilContextProvider(definitionType); this.IsValid = true; var startMeta = MetadataParser.EnumerateAndBind(definitionType); if (startMeta.Count() == 0) { throw new InvalidOperationException( string.Format( "No metadata found in language definition '{0}'", definitionType.FullName)); } this.SymbolResolver = new CilSymbolRefResolver(); this.Start = CilSymbolRef.Create(typeof(void)); var collector = new MetadataCollector(logging); collector.AddSymbol(Start); foreach (var meta in startMeta) { collector.AddMeta(meta); } if (collector.HasInvalidData) { this.IsValid = false; } this.metadata = collector.Metadata; this.productions = collector.Productions; foreach (var tid in collector.Symbols) { SymbolResolver.Link(tid); } var categories = new [] { SymbolCategory.Beacon, SymbolCategory.DoNotInsert, SymbolCategory.DoNotDelete, SymbolCategory.ExplicitlyUsed }; foreach (var category in categories) { foreach (var symbol in metadata.SelectMany(m => m.GetSymbolsInCategory(category))) { var def = SymbolResolver.Resolve(symbol); def.Categories |= category; } } if (productions.Count == 0) { throw new InvalidOperationException( string.Format( "Language definition '{0}' should have at least one parse production", definitionType.FullName)); } this.mergers = metadata .SelectMany(meta => meta.GetMergers(collector.Symbols)) .ToArray(); var terminals = collector.Symbols.Except(productions.Select(r => r.Outcome).Distinct()).ToArray(); var scanDataCollector = new ScanDataCollector(terminals, logging); scanDataCollector.AddCondition(definitionType); if (scanDataCollector.HasInvalidData) { this.IsValid = false; } conditions = scanDataCollector.Conditions; LinkRelatedTokens(conditions); var allTerms = (from t in scanDataCollector.Terminals let def = SymbolResolver.Resolve(t) where def != null select def) .Distinct(); var termsProducedByScanner = (from cond in scanDataCollector.Conditions from prod in cond.Matchers from outcome in prod.AllOutcomes let def = SymbolResolver.Resolve(outcome) where def != null select def) .Distinct(); var undefinedTerminals = allTerms .Where(symbol => !IsSpecialSymbol(symbol)) .Except(termsProducedByScanner); CheckAllScanRulesDefined(undefinedTerminals, source.Origin, logging); precedence = metadata.SelectMany(m => m.GetSymbolPrecedence()).ToList(); LocalContextProviders = metadata.SelectMany((m, index) => m.GetLocalContextProviders()); this.Reports = metadata.SelectMany(m => m.GetReports()).ToArray(); }
public Symbol GetSymbol(CilSymbolRef tid) { CilSymbol def = Resolve(tid); return(def == null ? null : def.Symbol); }
public bool Contains(CilSymbolRef symbolRef) { return(symbolRef != null && (ResolveLiteral(symbolRef.Literal) != null || ResolveTokenType(symbolRef.Type) != null)); }
public void Link(CilSymbolRef first) { Ensure(first); }