예제 #1
0
 public bool Contains(Symbol symbol)
 {
     foreach (var s in Symbols)
         if (s == symbol)
             return true;
     return false;
 }
예제 #2
0
        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);
        }
예제 #3
0
        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;
            }
        }
예제 #4
0
 public Production(Symbol startSimbol, List<Formula> formulas)
 {
     NTerm = startSimbol;
     NTerm.Type = SymbolType.NonTerminal;
     Formulas = formulas;
 }
예제 #5
0
        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];
            }
        }
예제 #6
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;
            }
        }
예제 #7
0
 public int IndexOf(Symbol symbol)
 {
     if (Contains(symbol) == false)
         return -1;
     return Symbols.IndexOf(symbol);
 }
예제 #8
0
 public static ParseTree FromSymbol(Symbol symbol)
 {
     ParseTree tree = new ParseTree(new Symbol(symbol.Name, symbol.Type));
     return tree;
 }
예제 #9
0
 public ParseTree(Symbol symbol, List<ParseTree> children)
 {
     Symbol = symbol;
     Children = new List<ParseTree>();
     Add(children);
 }
예제 #10
0
 public ParseTree(Symbol symbol)
     : this(symbol, new List<ParseTree>())
 {
 }