public Production(ConfigSection section, SyntacticConfigurationFile config) { this.Key = new Symbol(config.GetRule(SyntacticConfigurationFile.RULE_PRODUCTION_PREFIX_KEY) + section.Header.First(), config); this.Rules = new List <Rule>(); foreach (var entry in section.Header) { if (entry.StartsWith(SyntacticConfigurationFile.HEADER_EPSILON_PREFIX)) { string value = entry.Remove(0, SyntacticConfigurationFile.HEADER_EPSILON_PREFIX.Length); if (bool.TryParse(value, out bool canBeEpsilon)) { this.CanBeEpsilon = canBeEpsilon; } else { Log.WriteLineWarning($"Unable to determine if {this.Key.ID} production can be epsilon or not from: '{value}'."); } } } foreach (var line in section.Body.Where(line => !string.IsNullOrWhiteSpace(line))) { var rule = new Rule(this.Key, line, config); this.Rules.Add(rule); } }
private void ProcessSection(ConfigSection section, SyntacticConfigurationFile config) { Debug.Assert(section.Header.Any(entry => !string.IsNullOrEmpty(entry)), $"Cannot have empty {SyntacticConfigurationFile.SECTION_TAG_PRODUCTION} header at {section.GetLocation()}"); string key = section.Header.First(); var production = new Production(section, config); this._productions.Add(key, production); }
private void AddExtraStartProduction(SyntacticConfigurationFile config) { // Insert the S' -> S production to guarentee one /single/ rule in the start production. string start = config.GetRule(SyntacticConfigurationFile.RULE_START_KEY).ToString(); string realStart = start + START_PRIME; char prefix = config.GetRule(SyntacticConfigurationFile.RULE_PRODUCTION_PREFIX_KEY); var section = new ConfigSection( $"#{SyntacticConfigurationFile.SECTION_TAG_PRODUCTION} {realStart}", new string[] { $"{prefix}{start}" }, $"({nameof(ProductionTable)}.cs)", -1 ); ProcessSection(section, config); }
public ProductionTable(SyntacticConfigurationFile config) { this._productions = new Dictionary <string, Production>(); this._first = new Dictionary <string, HashSet <Symbol> >(); this.AddExtraStartProduction(config); foreach (var section in config.GetSections(SyntacticConfigurationFile.SECTION_TAG_PRODUCTION)) { ProcessSection(section, config); } this.TransformEpsilonTransitions(config); this.ComputeFirst(); }
public Rule(Symbol key, string line, SyntacticConfigurationFile config) { this.Key = key; this.Symbols = new List <Symbol>(); var sb = new StringBuilder(); var symbols = line.Split(' '); foreach (var symbolData in symbols) { var symbol = new Symbol(symbolData, config); this.Symbols.Add(symbol); sb.Append(symbol.ID); } this.TextRepresentation = sb.ToString(); }
private void TransformEpsilonTransitions(SyntacticConfigurationFile config) { var productionsWithEpsilonTransitions = new HashSet <string>(this._productions.Where(entry => entry.Value.CanBeEpsilon).Select(entry => entry.Key)); foreach (var entry in this._productions) { var allNewRules = new List <Rule?>(); foreach (var rule in entry.Value.Rules) { foreach (var newRule in Permute(rule, 0, productionsWithEpsilonTransitions, false)) { allNewRules.Add(newRule); } } foreach (var newRule in allNewRules.Where(newRule => newRule != null)) { if (!entry.Value.Rules.Contains(newRule)) { entry.Value.Rules.Add(newRule); } } } }