public bool Contains(Symbol symbol) { foreach (var s in Symbols) if (s == symbol) return true; return false; }
public Formula Find(Symbol NTerm, Symbol Term, List<Symbol> FlwTerms) { var production = Grammar.FindProduction(NTerm); if (production == null) return null; /* * case: * expr := if_expr | for_expr; * if_expr := TOKEN_IF cond_expr expr */ if (IsNTermProduction(production)) return FindNTermFormula(NTerm, Term, FlwTerms); return FindTermFormula(NTerm, Term, FlwTerms); }
public Grammar Parse() { if (!Valid) return null; try { List<string> terminals = new List<string>(); List<string> nonterminals = new List<string>(); List<Production> x = new List<Production>(); Symbol axiom = new Symbol("$"); string bnf = File.ReadAllText(Filename); Symbol current = new Symbol("$"); List<Symbol> symbolStack = new List<Symbol>(); List<Formula> formulaStack = new List<Formula>(); List<string> symbols = new List<string>(); var tokens = scanner.Tokenize(bnf).ToList(); for (int i = 0; i < tokens.Count; i++) { if ((i + 1 < tokens.Count) && tokens[i + 1].Type == "TOKEN_EQUALS") { current = new Symbol(tokens[i].Value, SymbolType.NonTerminal); nonterminals.Add(current.Name); if (i == 0) { axiom = new Symbol(current.Name); } continue; } if(tokens[i].Type == "TOKEN_EQUALS") { continue; } if(tokens[i].Type == "TOKEN_OR") { formulaStack.Add(new Formula(symbolStack)); symbolStack = new List<Symbol>(); continue; } if(tokens[i].Type == "TOKEN_SYMBOL") { symbolStack.Add(new Symbol(tokens[i].Value)); symbols.Add(tokens[i].Value); continue; } if(tokens[i].Type == "TOKEN_SEMICOLON") { formulaStack.Add(new Formula(symbolStack)); x.Add(new Production(current, formulaStack)); symbolStack = new List<Symbol>(); formulaStack = new List<Formula>(); continue; } if(tokens[i].Type == "TOKEN_EOF") { symbolStack.Add(Grammar.EOF); symbols.Add("(end)"); continue; } if(tokens[i].Type == "TOKEN_EMPTY") { symbolStack.Add(Grammar.EMPTY); symbols.Add("(empty)"); continue; } } List<Symbol> t = new List<Symbol>(); List<Symbol> v = new List<Symbol>(); var tempv = nonterminals.Distinct().ToList(); foreach (var nonterminal in tempv) { v.Add(new Symbol(nonterminal)); } foreach(var terminal in symbols.Distinct().ToList()) { if (tempv.Contains(terminal) == false) t.Add(new Symbol(terminal, SymbolType.Terminal)); } foreach(var production in x) { foreach(var formula in production.Formulas) { foreach(var symbol in formula.Symbols) { foreach(var terminal in t) { if(symbol.Name == terminal.Name) { symbol.Type = SymbolType.Terminal; break; } } } } } return new Grammar(t, v, x, axiom); } catch(Exception e) { Console.WriteLine("Exception: BNF parsing error!"); Console.WriteLine(e.ToString()); return null; } }
public Production(Symbol startSimbol, List<Formula> formulas) { NTerm = startSimbol; NTerm.Type = SymbolType.NonTerminal; Formulas = formulas; }
Formula FindNTermFormula(Symbol NTerm, Symbol Term, List<Symbol> FlwTerms) { var p = Grammar.FindProduction(NTerm); if(p.IsRecursive) { // .es // program := expr program; if(p.Formulas.Count == 1) { return p.Formulas[0]; } else if(p.Formulas.Count == 2) { if(p.Empty != null) { if (FlwTerms.Count <= 1) return p.Empty; else { foreach (var formula in p.Formulas) if (formula.Empty == false) return formula; } } } } List<Formula> formulas = new List<Formula>(); foreach (var formula in p.Formulas) { if(formula.Symbols.Count == 1 && formula.Contains(Grammar.EMPTY) && FlwTerms.Count == 0 && Term == Grammar.EOF) return new Formula(new List<Symbol>()); var production = Grammar.FindProduction(formula.Symbols[0]); if (production == null) continue; if(!IsNTermProduction(production)) { if (FindTermFormula(production.NTerm, Term, FlwTerms) != null) formulas.Add(formula); } else { if (FindNTermFormula(production.NTerm, Term, FlwTerms) != null) formulas.Add(formula); } } if (formulas.Count == 0) { return p.Empty; // return null if p.ContainsEmptyFormula == false } else if (formulas.Count == 1) return formulas[0]; else { // controlla la presenza di una produzione ricorsiva return formulas[0]; } }
Formula FindTermFormula(Symbol NTerm, Symbol Term, List<Symbol> FlwTerms) { List<Formula> formulas = new List<Formula>(); var production = Grammar.FindProduction(NTerm); foreach (var formula in production.Formulas) if (First(formula) == Term) formulas.Add(formula); if (formulas.Count == 0) { return production.Empty; // maybe null } else if (formulas.Count == 1) return formulas[0]; else { Formula currentFormula = null; int score = 0; foreach (var formula in formulas) { int _score = 0; for (int i = 0; i <= formula.Symbols.Count; i++) { if (formula.Symbols.Count > i + 1 && FlwTerms.Count > i) { var s1 = formula.Symbols[i + 1]; var s2 = FlwTerms[i]; if (s1 == s2) { _score++; // error found //if (formula.Symbols.Count == FlwTerms.Count) // return formula; } else break; } } if (currentFormula == null || _score > score) { currentFormula = formula; score = _score; } } return currentFormula; } }
public int IndexOf(Symbol symbol) { if (Contains(symbol) == false) return -1; return Symbols.IndexOf(symbol); }
public static ParseTree FromSymbol(Symbol symbol) { ParseTree tree = new ParseTree(new Symbol(symbol.Name, symbol.Type)); return tree; }
public ParseTree(Symbol symbol, List<ParseTree> children) { Symbol = symbol; Children = new List<ParseTree>(); Add(children); }
public ParseTree(Symbol symbol) : this(symbol, new List<ParseTree>()) { }