コード例 #1
0
ファイル: LL1Parser.cs プロジェクト: realn0whereman/MiniRE
        public Node doParse()
        {
            //% is epsilon.

            Stack<string> tokens = new Stack<string>();
            tokens.Push("$");
            tokens.Push("<MiniRE-program>");

            Stack<Node> nodes = new Stack<Node>();
            Node miniRE = new Node();

            while (tokens.Count != 0)
            {
                string topElem = tokens.Pop();
                string nextToken = scanner.peekToken();

                if (nextToken == "$")
                {
                    if (topElem == "$")
                        break;
                    else
                        throw new RDParser.SyntaxError("All tokens not popped off stack");
                }

                if (topElem.Contains('<') && topElem.Contains('>'))
                {
                    //This is a non-term, we need to look up and replace.
                    List<string> newrule;
                    try
                    {
                        if (isID(nextToken))
                            newrule = parsetable.getRuleMatchingToken(topElem, "ID");
                        else if(isREGEX(nextToken))
                            newrule = parsetable.getRuleMatchingToken(topElem, "REGEX");
                        else if(isASCIISTR(nextToken))
                            newrule = parsetable.getRuleMatchingToken(topElem, "ASCII-STR");
                        else
                            newrule = parsetable.getRuleMatchingToken(topElem, nextToken);
                    }
                    catch (KeyNotFoundException e)
                    {
                        throw new RDParser.SyntaxError("Invalid token in position.");
                    }
                    //Take the existing rule, create its node, add to top elem on stack, pop top elem if full.

                    Node newElem = GetNodeFromRuleName(topElem);
                    if (!(newrule.Count == 0 && newrule[0] == "%"))
                    {
                        if (nodes.Count != 0 && nodes.Peek().IsFull)
                            nodes.Pop();
                        if (nodes.Count != 0)
                            nodes.Peek().Nodes.Add(newElem);

                        if (nodes.Count != 0 && nodes.Peek().IsFull && nodes.Peek() is MiniRE)
                        {
                            miniRE = nodes.Pop();
                        }
                        else if (nodes.Count != 0 && nodes.Peek().IsFull)
                            nodes.Pop();

                        if (!newElem.IsFull && newrule[0] != "%")
                        {
                            nodes.Push(newElem);
                        }
                        newrule = new List<string>(newrule);
                        newrule.Reverse();

                        if (newrule.Count > 0 && newrule[0] != "%")
                        {
                            foreach (string s in newrule)
                            {
                                tokens.Push(s);
                            }
                        }
                    }
                    else
                    {
                        StringNode sn = new StringNode();
                        sn.Token = "%";
                        newElem.Nodes.Add(sn);
                        nodes.Peek().Nodes.Add(newElem);

                        if (nodes.Peek().IsFull && nodes.Peek() is MiniRE)
                            miniRE = nodes.Pop();
                    }

                }
                else
                {
                    nextToken = scanner.getToken();
                    //Is a terminal; must match top of stack, possibly do stuff with AST depending on token.
                    if (topElem == nextToken)
                    {
                        switch (nextToken)
                        {
                            case "maxfreqstring":
                                AssignmentStatement xyz = (AssignmentStatement)nodes.Peek();
                                xyz.Type = AssignmentStatementType.MaxFreqString;
                                break;
                            case "#":
                                AssignmentStatement xyza = (AssignmentStatement)nodes.Peek();
                                xyza.Type = AssignmentStatementType.Length;
                                break;
                            case "replace":
                                OtherStatement abc = (OtherStatement)nodes.Peek();
                                abc.Mode = OtherStatementMode.Replace;
                                break;
                            case "print":
                                OtherStatement bcd = (OtherStatement)nodes.Peek();
                                bcd.Mode = OtherStatementMode.Print;
                                break;
                            case "recursivereplace":
                                OtherStatement cde = (OtherStatement)nodes.Peek();
                                cde.Mode = OtherStatementMode.RecursiveReplace;
                                break;
                            case "diff":
                                BinOp op1 = (BinOp)nodes.Peek();
                                StringNode n1 = new StringNode();
                                n1.Token = "diff";
                                op1.Nodes.Add(n1);
                                break;
                            case "union":
                                BinOp op2 = (BinOp)nodes.Peek();
                                StringNode n2 = new StringNode();
                                n2.Token = "union";
                                op2.Nodes.Add(n2);
                                break;
                            case "inters":
                                BinOp op3 = (BinOp)nodes.Peek();
                                StringNode n3 = new StringNode();
                                n3.Token = "inters";
                                op3.Nodes.Add(n3);
                                break;
                            default:
                                break;
                        }
                    }
                    else if (topElem == "REGEX" && nextToken[0] == '\'' && nextToken[nextToken.Length - 1] == '\'')
                    {
                        Regex re = new Regex();
                        re.Pattern = nextToken.Substring(1, nextToken.Length - 2);
                        nodes.Peek().Nodes.Add(re);
                        if (nodes.Peek().IsFull)
                            nodes.Pop();
                    }
                    else if (topElem == "ASCII-STR" && nextToken[0] == '"' && nextToken[nextToken.Length - 1] == '"')
                    {
                        Node top = nodes.Peek();
                        if (top is OtherStatement)
                        {
                            OtherStatement nd = (OtherStatement)top;
                            nd.ReplaceText = nextToken.Substring(1, nextToken.Length-2);
                        }
                        else if (top is Filename)
                        {
                            Filename fn = (Filename)top;
                            fn.Path = nextToken.Substring(1, nextToken.Length-2);
                        }
                        if (top.IsFull)
                            nodes.Pop();
                    }
                    else if (topElem == "ID")
                    {
                        StringNode sn = new StringNode();
                        sn.Token = nextToken;
                        nodes.Peek().Nodes.Add(sn);
                        if (nodes.Peek().IsFull)
                            nodes.Pop();
                    }
                    else
                    {
                        throw new RDParser.SyntaxError("Token did not match top of LL(1) Parse Stack.");
                    }
                }
            }

            return miniRE;
        }
コード例 #2
0
ファイル: MiniRETest.cs プロジェクト: realn0whereman/MiniRE
        public void Union()
        {
            //begin
            //x = (find 'a(b|c)' in abc.txt) union (find 'bc in abc.txt)
            //end

            SymbolTable table = new SymbolTable();

            MiniRE miniRe = new MiniRE();

            StatementList sl = new StatementList();
            miniRe.StatementList = sl;

            Statement statement = new Statement();
            statement.Id = new StringNode("x");
            sl.Statement = statement;

            AssignmentStatement as1 = new AssignmentStatement();
            statement.AssignmentStatement = as1;

            Exp exp = new Exp();
            as1.Exp = exp;

            #region First find

            Term t1 = new Term();
            exp.Term = t1;

            Regex r1 = new Regex();
            r1.Pattern = "([a-zA-Z])*ment([a-zA-Z])*";
            t1.Regex = r1;

            Filename file1 = new Filename();
            file1.Path = "../../../TestFiles/file1.txt";
            t1.Filename = file1;

            #endregion

            ExpTail expTail = new ExpTail();
            exp.Tail = expTail;

            BinOp bop = new BinOp();
            expTail.Binop = bop;

            StringNode operation = new StringNode("union");
            bop.Operation = operation;

            #region Second find

            Term t2 = new Term();
            expTail.Term = t2;

            ExpTail expTail2 = new ExpTail();
            expTail.Tail = expTail2;

            Regex r2 = new Regex();
            r2.Pattern = "([a-zA-Z])*(a|A)([a-zA-Z])*";
            t2.Regex = r2;

            Filename file2 = new Filename();
            file2.Path = "../../../TestFiles/file2.txt";
            t2.Filename = file2;

            #endregion

            miniRe.Execute(table);
            StringMatchList matches = (StringMatchList) table["x"];

            Assert.AreEqual(8, matches.Length);

            String expected = "{\"mentor\"<'../../../TestFiles/file1.txt', 1>" +
                "\"filament\"<'../../../TestFiles/file1.txt', 1>" +
                "\"argument\"<'../../../TestFiles/file1.txt', 1>" +
                "\"argumentative\"<'../../../TestFiles/file1.txt', 1><'../../../TestFiles/file2.txt', 1>" +
                "\"Tournament\"<'../../../TestFiles/file1.txt', 1>" +
                "\"Argument\"<'../../../TestFiles/file2.txt', 1>" +
                "\"predicament\"<'../../../TestFiles/file2.txt', 1>" +
                "\"apple\"<'../../../TestFiles/file2.txt', 1>" +
            "}";

            Assert.AreEqual(expected, matches.ToString());
        }