예제 #1
0
        public void SequentialComposition(NFA nfa)
        {
            Dictionary <State, Dictionary <char, HashSet <State> > > transitions = nfa.GetTransitions();
            Dictionary <State, State> transform = new Dictionary <State, State> ();

            foreach (State state in nfa.GetStates())
            {
                if (state == 0)
                {
                    transform [state] = _finalState;
                }
                else
                {
                    transform [state] = AddState();
                }
            }

            foreach (State state1 in transitions.Keys)
            {
                foreach (char c in transitions[state1].Keys)
                {
                    foreach (State state2 in transitions[state1][c])
                    {
                        AddTransition(transform [state1], c, transform [state2]);
                    }
                }
            }

            _finalState = transform [nfa.GetFinalState()];
        }
예제 #2
0
        private int ParseMultipleRule(Node ruleNode, int currentRule, Dictionary <string, List <Node> > vars)
        {
            List <Node>          children      = ruleNode.GetChildren();
            List <List <Entry> > inputEntries  = new List <List <Entry> > ();
            List <List <Entry> > outputEntries = new List <List <Entry> > ();
            String policy;

            foreach (Node node in children[0].GetChildren())
            {
                if ((node.GetNodeType() != Node.Type.TENTRY) && (node.GetNodeType() != Node.Type.TEVENT))
                {
                    throw new CloudMakefile.ParseException("The children of TENTRIES node should be of TENTRY type.");
                }
                outputEntries.Add(NFA.ParseTreeNode(node));
            }
            foreach (Node node in children[1].GetChildren())
            {
                if ((node.GetNodeType() != Node.Type.TENTRY) && (node.GetNodeType() != Node.Type.TEVENT))
                {
                    throw new CloudMakefile.ParseException("The children of TENTRIES node should be of TENTRY type.");
                }
                inputEntries.Add(NFA.ParseTreeNode(node));
            }
            policy = ParseString(children [2]);

            return(ParseMultipleRule(inputEntries, outputEntries, policy, currentRule, vars,
                                     new Dictionary <string, NFA> ()));
        }
예제 #3
0
        private int ParseMultipleRule(List <List <Entry> > inputEntries, List <List <Entry> > outputEntries,
                                      string policy, int currentRule, Dictionary <string, List <Node> > mVars,
                                      Dictionary <string, NFA> vars)
        {
            if (mVars.Count == 0)
            {
                ParseSingleRule(inputEntries, outputEntries, policy, currentRule, vars);
                return(currentRule + 1);
            }

            string      varName  = mVars.First().Key;
            List <Node> nodeList = mVars [varName];
            int         nextRule = currentRule;

            foreach (Node node in nodeList)
            {
                Dictionary <string, List <Node> > tempMVars = new Dictionary <string, List <Node> > (mVars);
                Dictionary <string, NFA>          tempVars  = new Dictionary <string, NFA> (vars);
                List <Entry> entryList = NFA.ParseTreeNode(node);

                if ((entryList.Count != 1) || (entryList [0].IsVar() != false))
                {
                    throw new CloudMakefile.ParseException("Variables should return only one NFA when parsed.");
                }
                tempMVars.Remove(varName);
                tempVars [varName] = entryList [0].GetNFA();
                nextRule           = ParseMultipleRule(inputEntries, outputEntries, policy, nextRule, tempMVars, tempVars);
            }
            return(nextRule);
        }
예제 #4
0
        private DFA SubstituteEntries(List <Entry> entries, Dictionary <string, NFA> vars)
        {
            NFA nfa = new NFA();

            foreach (Entry entry in entries)
            {
                if (entry.IsVar())
                {
                    if (!vars.ContainsKey(entry.GetVar()))
                    {
                        throw new CloudMakefile.ParseException("Variable " + entry.GetVar() + " is not defined.");
                    }
                    nfa.SequentialComposition(vars [entry.GetVar()]);
                }
                else
                {
                    nfa.SequentialComposition(entry.GetNFA());
                }
            }

            return(nfa.ConvertToDFA());
        }
예제 #5
0
        static private void ParseTreeNode(Node node, List <Entry> entryList)
        {
            List <Node>    children = null;
            HashSet <char> alphabet = null;
            NFA            curNFA = null;
            State          state1, state2, chkState1, chkState2;

            switch (node.GetNodeType())
            {
            case Node.Type.TENTRY:
                children = node.GetChildren();
                if (children [0].GetNodeType() != Node.Type.TDIRPATH)
                {
                    throw new CloudMakefile.ParseException("A TDIRPATH node is expected as the first node of a " +
                                                           "TENTRY node.");
                }
                if (children [1].GetNodeType() != Node.Type.TNAME)
                {
                    throw new CloudMakefile.ParseException("A TNAME node is expected as the second node of a TENTRY " +
                                                           "node.");
                }
                if (children [2].GetNodeType() != Node.Type.TXMLPATH)
                {
                    throw new CloudMakefile.ParseException("A TXMLPATH node is expected as the third node of a " +
                                                           "TENTRY node.");
                }
                ParseTreeNode(children [0], entryList);
                ParseTreeNode(children [1], entryList);
                curNFA = EnsureLastNFA(entryList);
                state1 = curNFA.GetFinalState();
                state2 = curNFA.AddState();
                curNFA.AddTransition(state1, '.', state2);
                state1 = state2;
                state2 = curNFA.AddState();
                curNFA.AddTransition(state1, 'x', state2);
                state1 = state2;
                state2 = curNFA.AddState();
                curNFA.AddTransition(state1, 'm', state2);
                state1 = state2;
                state2 = curNFA.AddState();
                curNFA.AddTransition(state1, 'l', state2);
                curNFA.SetFinalState(state2);
                ParseTreeNode(children [2], entryList);
                break;

            case Node.Type.TEVENT:
                children = node.GetChildren();
                if (children [0].GetNodeType() != Node.Type.TDIRPATH)
                {
                    throw new CloudMakefile.ParseException("A TDIRPATH node is expected as the first node of a " +
                                                           "TEVENT node.");
                }
                if (children [1].GetNodeType() != Node.Type.TNAME)
                {
                    throw new CloudMakefile.ParseException("A TNAME node is expected as the second node of a TEVENT " +
                                                           "node.");
                }
                ParseTreeNode(children [0], entryList);
                ParseTreeNode(children [1], entryList);
                break;

            case Node.Type.TDIRPATH:
                children = node.GetChildren();
                foreach (Node child in children)
                {
                    if (child.GetNodeType() != Node.Type.TNAME)
                    {
                        throw new CloudMakefile.ParseException("A TNAME node is expected as the child node of a " +
                                                               "TDIRPATH node.");
                    }
                    ParseTreeNode(child, entryList);
                    curNFA = EnsureLastNFA(entryList);
                    state1 = curNFA.GetFinalState();
                    state2 = curNFA.AddState();
                    curNFA.AddTransition(state1, Path.DirectorySeparatorChar, state2);
                    curNFA.SetFinalState(state2);
                }
                break;

            case Node.Type.TXMLPATH:
                Node lastNode = new Node("ASTERISK(ATOM(SEQUENCE(CHOICE(RANGE(CHAR(A),CHAR(Z)),RANGE(CHAR(a)," +
                                         "CHAR(z)),RANGE(CHAR(0),CHAR(9)),CHAR(@),CHAR(_)))))");

                children = node.GetChildren();
                foreach (Node child in children)
                {
                    if (child.GetNodeType() != Node.Type.TNAME)
                    {
                        throw new CloudMakefile.ParseException("A TNAME node is expected as the child node of a " +
                                                               "TXMLPATH node.");
                    }
                    curNFA = EnsureLastNFA(entryList);
                    state1 = curNFA.GetFinalState();
                    state2 = curNFA.AddState();
                    curNFA.AddTransition(state1, '{', state2);
                    curNFA.SetFinalState(state2);
                    ParseTreeNode(child, entryList);
                    curNFA = EnsureLastNFA(entryList);
                    state1 = curNFA.GetFinalState();
                    state2 = curNFA.AddState();
                    curNFA.AddTransition(state1, '}', state2);
                    curNFA.SetFinalState(state2);
                }
                curNFA    = EnsureLastNFA(entryList);
                chkState1 = curNFA.GetFinalState();
                state1    = chkState1;
                state2    = curNFA.AddState();
                curNFA.AddTransition(state1, '{', state2);
                curNFA.SetFinalState(state2);
                ParseTreeNode(lastNode, entryList);
                state1    = curNFA.GetFinalState();
                state2    = curNFA.AddState();
                chkState2 = state2;
                curNFA.AddTransition(state1, '}', state2);
                curNFA.SetFinalState(state2);
                curNFA.AddTransition(chkState1, Char.MinValue, chkState2);
                curNFA.AddTransition(chkState2, Char.MinValue, chkState1);
                break;

            case Node.Type.TNAME:
                children = node.GetChildren();
                foreach (Node child in children)
                {
                    if (child.GetNodeType() == Node.Type.TSEQUENCE)
                    {
                        ParseTreeNode(child, entryList);
                    }
                    else if (child.GetNodeType() == Node.Type.TVAR)
                    {
                        ParseTreeNode(child, entryList);
                    }
                    else
                    {
                        throw new CloudMakefile.ParseException("A TSEQUENCE or TVAR node is expected as the child " +
                                                               "node of a TNAME node.");
                    }
                }
                break;

            case Node.Type.TSEQUENCE:
                children = node.GetChildren();
                foreach (Node child in children)
                {
                    if ((child.GetNodeType() != Node.Type.TASTERISK) && (child.GetNodeType() != Node.Type.TPLUS) &&
                        (child.GetNodeType() != Node.Type.TQUESTIONMARK) && (child.GetNodeType() != Node.Type.TCHAR) &&
                        (child.GetNodeType() != Node.Type.TCHOICE) && (child.GetNodeType() != Node.Type.TNO_CHOICE) &&
                        (child.GetNodeType() != Node.Type.TUNION) && (child.GetNodeType() != Node.Type.TATOM))
                    {
                        throw new CloudMakefile.ParseException("An appropriate node is expected as the child node " +
                                                               "of a TSEQUENCE node.");
                    }
                    ParseTreeNode(child, entryList);
                }
                break;

            case Node.Type.TATOM:
                children = node.GetChildren();
                if (children [0].GetNodeType() != Node.Type.TSEQUENCE)
                {
                    throw new CloudMakefile.ParseException("A TSEQUENCE node is expected as the first node of a " +
                                                           "TATOM node.");
                }
                ParseTreeNode(children [0], entryList);
                break;

            case Node.Type.TASTERISK:
                children = node.GetChildren();
                if ((children [0].GetNodeType() != Node.Type.TCHAR) &&
                    (children [0].GetNodeType() != Node.Type.TCHOICE) &&
                    (children [0].GetNodeType() != Node.Type.TNO_CHOICE) &&
                    (children [0].GetNodeType() != Node.Type.TUNION) &&
                    (children [0].GetNodeType() != Node.Type.TATOM))
                {
                    throw new CloudMakefile.ParseException("An appropriate node is expected as the child node of a " +
                                                           "TASTERISK node.");
                }
                curNFA    = EnsureLastNFA(entryList);
                chkState1 = curNFA.GetFinalState();
                ParseTreeNode(children [0], entryList);
                chkState2 = curNFA.GetFinalState();
                curNFA.AddTransition(chkState1, Char.MinValue, chkState2);
                curNFA.AddTransition(chkState2, Char.MinValue, chkState1);
                break;

            case Node.Type.TPLUS:
                children = node.GetChildren();
                if ((children [0].GetNodeType() != Node.Type.TCHAR) &&
                    (children [0].GetNodeType() != Node.Type.TCHOICE) &&
                    (children [0].GetNodeType() != Node.Type.TNO_CHOICE) &&
                    (children [0].GetNodeType() != Node.Type.TUNION) &&
                    (children [0].GetNodeType() != Node.Type.TATOM))
                {
                    throw new CloudMakefile.ParseException("An appropriate node is expected as the child node of a " +
                                                           "TPLUS node.");
                }
                curNFA    = EnsureLastNFA(entryList);
                chkState1 = curNFA.GetFinalState();
                ParseTreeNode(children [0], entryList);
                chkState2 = curNFA.GetFinalState();
                curNFA.AddTransition(chkState2, Char.MinValue, chkState1);
                break;

            case Node.Type.TQUESTIONMARK:
                children = node.GetChildren();
                if ((children [0].GetNodeType() != Node.Type.TCHAR) &&
                    (children [0].GetNodeType() != Node.Type.TCHOICE) &&
                    (children [0].GetNodeType() != Node.Type.TNO_CHOICE) &&
                    (children [0].GetNodeType() != Node.Type.TUNION) &&
                    (children [0].GetNodeType() != Node.Type.TATOM))
                {
                    throw new CloudMakefile.ParseException("An appropriate node is expected as the child node of a " +
                                                           "TQUESTIONMARK node.");
                }
                curNFA    = EnsureLastNFA(entryList);
                chkState1 = curNFA.GetFinalState();
                ParseTreeNode(children [0], entryList);
                chkState2 = curNFA.GetFinalState();
                curNFA.AddTransition(chkState1, Char.MinValue, chkState2);
                break;

            case Node.Type.TCHOICE:
                alphabet = new HashSet <char> ();
                children = node.GetChildren();
                foreach (Node child in children)
                {
                    if ((child.GetNodeType() != Node.Type.TCHAR) && (child.GetNodeType() != Node.Type.TRANGE))
                    {
                        throw new CloudMakefile.ParseException("A TCHAR and a TRANGE node is expected as the child " +
                                                               "node of a TCHOICE node.");
                    }
                    if (child.GetNodeType() == Node.Type.TRANGE)
                    {
                        Tuple <char, char> range = child.GetRange();

                        for (char c = range.Item1; c <= range.Item2; c++)
                        {
                            alphabet.Add(c);
                        }
                    }
                    else
                    {
                        alphabet.Add(child.GetChar());
                    }
                }
                curNFA = EnsureLastNFA(entryList);
                state1 = curNFA.GetFinalState();
                state2 = curNFA.AddState();
                foreach (char c in alphabet)
                {
                    curNFA.AddTransition(state1, c, state2);
                }
                curNFA.SetFinalState(state2);
                break;

            case Node.Type.TNO_CHOICE:
                alphabet = new HashSet <char> ();
                for (char c = 'A'; c <= 'Z'; c++)
                {
                    alphabet.Add(c);
                }
                for (char c = 'a'; c <= 'z'; c++)
                {
                    alphabet.Add(c);
                }
                for (char c = '0'; c <= '9'; c++)
                {
                    alphabet.Add(c);
                }
                alphabet.Add('_');
                alphabet.Add('@');
                children = node.GetChildren();
                foreach (Node child in children)
                {
                    if (child.GetNodeType() == Node.Type.TRANGE)
                    {
                        Tuple <char, char> range = child.GetRange();

                        for (char c = range.Item1; c <= range.Item2; c++)
                        {
                            alphabet.Remove(c);
                        }
                    }
                    else
                    {
                        alphabet.Remove(child.GetChar());
                    }
                }
                state1 = curNFA.GetFinalState();
                state2 = curNFA.AddState();
                curNFA = EnsureLastNFA(entryList);
                foreach (char c in alphabet)
                {
                    curNFA.AddTransition(state1, c, state2);
                }
                curNFA.SetFinalState(state2);
                break;

            case Node.Type.TUNION:
                children = node.GetChildren();
                if (children [0].GetNodeType() != Node.Type.TSEQUENCE)
                {
                    throw new CloudMakefile.ParseException("A TSEQUENCE node is expected as the first node of a " +
                                                           "TUNION node.");
                }
                if (children [1].GetNodeType() != Node.Type.TSEQUENCE)
                {
                    throw new CloudMakefile.ParseException("A TSEQUENCE node is expected as the second node of a " +
                                                           "TUNION node.");
                }
                curNFA = EnsureLastNFA(entryList);
                state1 = curNFA.GetFinalState();
                ParseTreeNode(children [0], entryList);
                chkState1 = curNFA.GetFinalState();
                curNFA.SetFinalState(state1);
                ParseTreeNode(children [1], entryList);
                chkState2 = curNFA.GetFinalState();
                state2    = curNFA.AddState();
                curNFA.AddTransition(chkState1, Char.MinValue, state2);
                curNFA.AddTransition(chkState2, Char.MinValue, state2);
                curNFA.SetFinalState(state2);
                break;

            case Node.Type.TVAR:
                string varName = CloudMakefile.ParseString(node);

                entryList.Add(new Entry(varName));
                break;

            case Node.Type.TCHAR:
                char character = node.GetChar();

                curNFA = EnsureLastNFA(entryList);
                state1 = curNFA.GetFinalState();
                state2 = curNFA.AddState();
                curNFA.AddTransition(state1, character, state2);
                curNFA.SetFinalState(state2);
                break;

            default:
                throw new CloudMakefile.ParseException("Unhandled node type: " + node.GetNodeType().ToString());
            }
        }
예제 #6
0
파일: Entry.cs 프로젝트: tedgoud/CloudMake
 public Entry(NFA nfa)
 {
     _isVar = false;
     _nfa   = nfa;
 }