示例#1
0
 private GrammarParser(Lexer lex, Func <char, T> mkExprinal)
 {
     lexer           = lex;
     this.mkExprinal = mkExprinal;
     startvar        = null;
     productions     = new List <Grammars.Production>();
 }
示例#2
0
 private GrammarParser(Lexer lex, Func <string, Automaton <T> > parseRegex)
 {
     lexer              = lex;
     this.parseRegex    = parseRegex;
     startvar           = null;
     productions        = new List <Grammars.Production>();
     terminalMap        = new Dictionary <string, GrammarSymbol[]>();
     this.parsedRegexes = new Dictionary <Nonterminal, Automaton <T> >();
 }
示例#3
0
        private void Parse()
        {
            bool  done = false;
            Token cur  = null;
            Token last = null;

            Grammars.Nonterminal curlhs = ExpectNT();
            startvar = curlhs;

            ExpectArrow();
            List <Grammars.GrammarSymbol> currhs = new List <Grammars.GrammarSymbol>();

            while (!done)
            {
                last = cur;
                cur  = lexer.Next();

                switch (cur.t)
                {
                case TokenType.NT:
                    currhs.Add(new Grammars.Nonterminal(cur.content));
                    break;

                case TokenType.T:
                    currhs.Add(new Exprinal <T>(mkExprinal(cur.content[0]), cur.content));
                    break;

                case TokenType.OR:
                    productions.Add(new Grammars.Production(curlhs, currhs.ToArray()));
                    currhs.Clear();
                    break;

                case TokenType.ARR:
                    if (currhs.Count < 1)
                    {
                        throw new ParseException();
                    }
                    if (last.t != TokenType.NT)
                    {
                        throw new ParseException();
                    }

                    // downcast :(
                    Grammars.Nonterminal newlhs = (Grammars.Nonterminal)currhs[currhs.Count - 1];
                    currhs.RemoveAt(currhs.Count - 1);
                    productions.Add(new Grammars.Production(curlhs, currhs.ToArray()));
                    currhs.Clear();
                    curlhs = newlhs;
                    break;

                case TokenType.EOS:
                    productions.Add(new Grammars.Production(curlhs, currhs.ToArray()));
                    currhs.Clear();
                    done = true;
                    break;

                default:
                    throw new ParseException();
                }
            }
        }
示例#4
0
        private void Parse()
        {
            bool  done = false;
            Token cur  = null;
            Token last = null;

            Grammars.Nonterminal curlhs = ExpectNT();
            startvar = curlhs;

            ExpectArrow();
            List <Grammars.GrammarSymbol> currhs = new List <Grammars.GrammarSymbol>();

            while (!done)
            {
                last = cur;
                cur  = lexer.Next();

                switch (cur.t)
                {
                case TokenType.NT:
                    currhs.Add(Grammars.Nonterminal.CreateByParser(cur.content));
                    break;

                case TokenType.T:
                {
                    GrammarSymbol[] symbs;
                    if (!terminalMap.TryGetValue(cur.content, out symbs))
                    {
                        var aut = parseRegex(cur.content);
                        #region parse this terminal-regex as an automaton and compute symbs or set symbs to top nonterminal
                        int seq_length = -1;
                        if (aut.IsEpsilon)
                        {
                            symbs = new GrammarSymbol[] { };
                        }
                        else if (aut.InitialStateIsSource && aut.HasSingleFinalSink && aut.MoveCount == 1)
                        {
                            //just a single terminal
                            var move = aut.GetMoveFrom(aut.InitialState);
                            symbs = new GrammarSymbol[] { new Terminal <T>(move.Label) };
                        }
                        else if (aut.CheckIfSequence(out seq_length) && aut.HasSingleFinalSink && aut.IsEpsilonFree)
                        {
                            //collect all the elements and map them to individual terminals
                            //inline the automaton as sequence of terminals
                            symbs = new GrammarSymbol[seq_length];
                            int q = aut.InitialState;
                            int i = 0;
                            while (!aut.IsFinalState(q))
                            {
                                var move = aut.GetMoveFrom(q);
                                q        = move.TargetState;
                                symbs[i] = new Terminal <T>(move.Label);
                                i       += 1;
                            }
                        }
                        else
                        {
                            //introduce new nonterminal for the automaton
                            int id = __regexId++;
                            var nt = Nonterminal.MkNonterminalForRegex(id);
                            parsedRegexes[nt] = aut;
                            symbs             = new GrammarSymbol[] { nt };
                        }
                        terminalMap[cur.content] = symbs;
                        #endregion
                    }
                    currhs.AddRange(symbs);
                    //---
                    break;
                }

                case TokenType.OR:
                    productions.Add(new Grammars.Production(curlhs, currhs.ToArray()));
                    currhs.Clear();
                    break;

                case TokenType.ARR:
                    if (currhs.Count < 1)
                    {
                        throw new ParseException();
                    }
                    if (last.t != TokenType.NT)
                    {
                        throw new ParseException();
                    }

                    // downcast :(
                    Grammars.Nonterminal newlhs = (Grammars.Nonterminal)currhs[currhs.Count - 1];
                    currhs.RemoveAt(currhs.Count - 1);
                    productions.Add(new Grammars.Production(curlhs, currhs.ToArray()));
                    currhs.Clear();
                    curlhs = newlhs;
                    break;

                case TokenType.EOS:
                    productions.Add(new Grammars.Production(curlhs, currhs.ToArray()));
                    currhs.Clear();
                    done = true;
                    break;

                default:
                    throw new ParseException();
                }
            }
        }