Example #1
0
        /**
         * Returns the action with highest priority in the specified
         * set of states.
         *
         * @param set  the set of states for which to determine the action
         */
        private Action getAction(StateSet set)
        {
            states.reset(set);

            Action maxAction = null;

            Out.debug("Determining action of : " + set);

            while (states.hasMoreElements())
            {
                Action currentAction = action[states.nextElement()];

                if (currentAction != null)
                {
                    if (maxAction == null)
                    {
                        maxAction = currentAction;
                    }
                    else
                    {
                        maxAction = maxAction.getHigherPriority(currentAction);
                    }
                }
            }

            return(maxAction);
        }
        private void increaseSize(int length)
        {
            length = Math.Max(length + 1, 4 * p.Length);
            Out.debug("increasing length to " + length); //$NON-NLS-1$

            int[] pn = new int[length];
            int[] qn = new int[length];

            Array.Copy(p, 0, pn, 0, p.Length);
            Array.Copy(q, 0, qn, 0, q.Length);

            p = pn;
            q = qn;
        }
Example #3
0
        public void addRegExp(int regExpNum)
        {
            if (Options.DEBUG)
            {
                Out.debug("Adding nfa for regexp " + regExpNum + " :" + Out.NL + regExps.getRegExp(regExpNum));
            }

            IntPair nfa = insertNFA(regExps.getRegExp(regExpNum));

            IEnumerator lexStates = regExps.getStates(regExpNum).GetEnumerator();

            if (!lexStates.MoveNext())
            {
                lexStates = scanner.states.getInclusiveStates();
            }

            lexStates.Reset();

            while (lexStates.MoveNext())
            {
                int stateNum = (int)lexStates.Current;

                if (!regExps.isBOL(regExpNum))
                {
                    addEpsilonTransition(2 * stateNum, nfa.start);
                }

                addEpsilonTransition(2 * stateNum + 1, nfa.start);
            }


            if (regExps.getLookAhead(regExpNum) != null)
            {
                IntPair look = insertNFA(regExps.getLookAhead(regExpNum));

                addEpsilonTransition(nfa.end, look.start);

                Action a = regExps.getAction(regExpNum);
                a.setLookAction(true);

                isPushback[nfa.end] = true;
                action[look.end]    = a;
                isFinal[look.end]   = true;
            }
            else
            {
                action[nfa.end]  = regExps.getAction(regExpNum);
                isFinal[nfa.end] = true;
            }
        }
Example #4
0
        /**
         * Stores a new macro and its definition.
         *
         * @param name         the name of the new macro
         * @param definition   the definition of the new macro
         *
         * @return <code>true</code>, iff the macro name has not been
         *         stored before.
         */
        public bool insert(String name, RegExp definition)
        {
#if DEBUG_TRACE
            log.WriteLine("insert(String name = \"{0}\", RegExp definition = {1})", name, definition);
#endif // DEBUG_TRACE

            if (Options.DEBUG)
            {
                Out.debug("inserting macro " + name + " with definition :" + Out.NL + definition); //$NON-NLS-1$ //$NON-NLS-2$
            }
            used[name] = false;

            bool new_entry = !macros.ContainsKey(name);
            macros[name] = definition;
            return(new_entry);
        }
        public int insert(ArrayList stateList, Action action)
        {
            if (Options.DEBUG)
            {
                Out.debug("Inserting eofrule with statelist :" + Out.NL + stateList); //$NON-NLS-1$
                Out.debug("and action code :" + Out.NL + action.content + Out.NL);    //$NON-NLS-1$
            }

            states.Add(stateList);
            regExps.Add(null);
            actions.Add(action);
            BOL.Add(null);
            look.Add(null);
            lines.Add(null);

            return(states.Count - 1);
        }
        public int insert(int line, ArrayList stateList, RegExp regExp, Action action,
                          Boolean isBOL, RegExp lookAhead)
        {
            if (Options.DEBUG)
            {
                Out.debug("Inserting regular expression with statelist :" + Out.NL + stateList); //$NON-NLS-1$
                Out.debug("and action code :" + Out.NL + action.content + Out.NL);               //$NON-NLS-1$
                Out.debug("expression :" + Out.NL + regExp);                                     //$NON-NLS-1$
            }

            states.Add(stateList);
            regExps.Add(regExp);
            actions.Add(action);
            BOL.Add(isBOL);
            look.Add(lookAhead);
            lines.Add(line);

            return(states.Count - 1);
        }
Example #7
0
        public void addTransition(int start, int input, int dest)
        {
            Out.debug("Adding transition (" + start + ", " + input + ", " + dest + ")");

            int maxS = Math.Max(start, dest) + 1;

            ensureCapacity(maxS);

            if (maxS > numStates)
            {
                numStates = maxS;
            }

            if (table[start][input] != null)
            {
                table[start][input].addState(dest);
            }
            else
            {
                table[start][input] = new StateSet(estSize, dest);
            }
        }
Example #8
0
        public bool [] [] old_minimize()
        {
            int  i, j;
            char c;

            Out.print(numStates + " states before minimization, ");

            if (numStates == 0)
            {
                Out.error(ErrorMessages.ZERO_STATES);
                throw new GeneratorException();
            }

            if (Options.no_minimize)
            {
                Out.println("minimization skipped.");
                return(null);
            }

            // notequiv[i][j] == true <=> state i and state j are equivalent
            bool [] [] equiv = new bool [numStates] [];

            // list[i][j] contains all pairs of states that have to be marked "not equivalent"
            // if states i and j are recognized to be not equivalent
            StatePairList [] [] list = new StatePairList [numStates] [];

            // construct a triangular matrix equiv[i][j] with j < i
            // and mark pairs (final state, not final state) as not equivalent
            for (i = 1; i < numStates; i++)
            {
                list[i]  = new StatePairList[i];
                equiv[i] = new bool [i];
                for (j = 0; j < i; j++)
                {
                    // i and j are equivalent, iff :
                    // i and j are both final and their actions are equivalent and have same pushback behaviour or
                    // i and j are both not final

                    if (isFinal[i] && isFinal[j] && (isPushback[i] == isPushback[j]) && (isLookEnd[i] == isLookEnd[j]))
                    {
                        equiv[i][j] = action[i].isEquiv(action[j]) && !Options.emit_csharp; // C# #line directives get messed up by merged states
                    }
                    else
                    {
                        equiv[i][j] = !isFinal[j] && !isFinal[i] && (isPushback[i] == isPushback[j]) && (isLookEnd[i] == isLookEnd[j]);
                    }
                }
            }


            for (i = 1; i < numStates; i++)
            {
                Out.debug("Testing state " + i);

                for (j = 0; j < i; j++)
                {
                    if (equiv[i][j])
                    {
                        for (c = (char)0; c < numInput; c++)
                        {
                            if (equiv[i][j])
                            {
                                int p = table[i][c];
                                int q = table[j][c];
                                if (p < q)
                                {
                                    int t = p;
                                    p = q;
                                    q = t;
                                }
                                if (p >= 0 || q >= 0)
                                {
                                    // Out.debug("Testing input '"+c+"' for ("+i+","+j+")");
                                    // Out.debug("Target states are ("+p+","+q+")");
                                    if (p != q && (p == -1 || q == -1 || !equiv[p][q]))
                                    {
                                        equiv[i][j] = false;
                                        if (list[i][j] != null)
                                        {
                                            list[i][j].markAll(list, equiv);
                                        }
                                    }
                                    // printTable(equiv);
                                } // if (p >= 0) ..
                            }     // if (equiv[i][j]
                        }         // for (char c = 0; c < numInput ..

                        // if i and j are still marked equivalent..

                        if (equiv[i][j])
                        {
                            // Out.debug("("+i+","+j+") are still marked equivalent");

                            for (c = (char)0; c < numInput; c++)
                            {
                                int p = table[i][c];
                                int q = table[j][c];
                                if (p < q)
                                {
                                    int t = p;
                                    p = q;
                                    q = t;
                                }

                                if (p != q && p >= 0 && q >= 0)
                                {
                                    if (list[p][q] == null)
                                    {
                                        list[p][q] = new StatePairList();
                                    }
                                    list[p][q].addPair(i, j);
                                }
                            }
                        }
                        else
                        {
                            // Out.debug("("+i+","+j+") are not equivalent");
                        }
                    } // of first if (equiv[i][j])
                }     // of for j
            }         // of for i
              // }

            // printTable(equiv);

            return(equiv);
        }
Example #9
0
        /**
         * Constructs an NFA accepting the complement of the language
         * of a given NFA.
         *
         * Converts the NFA into a DFA, then negates that DFA.
         * Exponential state blowup possible and common.
         *
         * @param the NFA to construct the complement for.
         *
         * @return a pair of integers denoting the index of start
         *         and end state of the complement NFA.
         */
        private IntPair complement(IntPair nfa)
        {
            if (Options.DEBUG)
            {
                Out.debug("complement for " + nfa);
                Out.debug("NFA is :" + Out.NL + this);
            }

            int dfaStart = nfa.end + 1;

            // fixme: only need epsilon closure of states reachable from nfa.start
            epsilonFill();

            Hashtable dfaStates = new PrettyHashtable(numStates);
            ArrayList dfaVector = new PrettyArrayList(numStates);

            int numDFAStates    = 0;
            int currentDFAState = 0;

            StateSet currentState, newState;

            newState            = epsilon[nfa.start];
            dfaStates[newState] = new Integer(numDFAStates);
            dfaVector.Add(newState);

            if (Options.DEBUG)
            {
                Out.debug("pos DFA start state is :" + Out.NL + dfaStates + Out.NL + Out.NL + "ordered :" + Out.NL + dfaVector);
            }

            currentDFAState = 0;

            while (currentDFAState <= numDFAStates)
            {
                currentState = (StateSet)dfaVector[currentDFAState];

                for (char input = (char)0; input < numInput; input++)
                {
                    newState = DFAEdge(currentState, input);

                    if (newState.containsElements())
                    {
                        // Out.debug("DFAEdge for input "+(int)input+" and state set "+currentState+" is "+newState);

                        // Out.debug("Looking for state set "+newState);
                        Integer nextDFAState = (Integer)dfaStates[newState];

                        if (nextDFAState != null)
                        {
                            // Out.debug("FOUND!");
                            addTransition(dfaStart + currentDFAState, input, dfaStart + nextDFAState.intValue());
                        }
                        else
                        {
                            if (Options.dump)
                            {
                                Out.print("+");
                            }
                            // Out.debug("NOT FOUND!");
                            // Out.debug("Table was "+dfaStates);
                            numDFAStates++;

                            dfaStates[newState] = new Integer(numDFAStates);
                            dfaVector.Add(newState);

                            addTransition(dfaStart + currentDFAState, input, dfaStart + numDFAStates);
                        }
                    }
                }

                currentDFAState++;
            }

            // We have a dfa accepting the positive regexp.

            // Now the complement:
            if (Options.DEBUG)
            {
                Out.debug("dfa finished, nfa is now :" + Out.NL + this);
            }

            int start = dfaStart + numDFAStates + 1;
            int error = dfaStart + numDFAStates + 2;
            int end   = dfaStart + numDFAStates + 3;

            addEpsilonTransition(start, dfaStart);

            for (int i = 0; i < numInput; i++)
            {
                addTransition(error, i, error);
            }

            addEpsilonTransition(error, end);

            for (int s = 0; s <= numDFAStates; s++)
            {
                currentState = (StateSet)dfaVector[s];

                currentDFAState = dfaStart + s;

                // if it was not a final state, it is now in the complement
                if (!currentState.isElement(nfa.end))
                {
                    addEpsilonTransition(currentDFAState, end);
                }

                // all inputs not present (formerly leading to an implicit error)
                // now lead to an explicit (final) state accepting everything.
                for (int i = 0; i < numInput; i++)
                {
                    if (table[currentDFAState][i] == null)
                    {
                        addTransition(currentDFAState, i, error);
                    }
                }
            }

            // eliminate transitions leading to dead states
            if (live == null || live.Length < numStates)
            {
                live    = new bool [2 * numStates];
                visited = new bool [2 * numStates];
            }

            _end       = end;
            _dfaStates = dfaVector;
            _dfaStart  = dfaStart;
            removeDead(dfaStart);

            if (Options.DEBUG)
            {
                Out.debug("complement finished, nfa (" + start + "," + end + ") is now :" + this);
            }

            return(new IntPair(start, end));
        }
Example #10
0
        /**
         * Returns an DFA that accepts the same language as this NFA.
         * This DFA is usualy not minimal.
         */
        public DFA getDFA()
        {
            Hashtable dfaStates = new PrettyHashtable(numStates);
            ArrayList dfaVector = new PrettyArrayList(numStates);

            DFA dfa = new DFA(2 * numLexStates, numInput);

            int numDFAStates    = 0;
            int currentDFAState = 0;

            Out.println("Converting NFA to DFA : ");

            epsilonFill();

            StateSet currentState, newState;

            for (int i = 0; i < 2 * numLexStates; i++)
            {
                newState = epsilon[i];

                dfaStates[newState] = new Integer(numDFAStates);
                dfaVector.Add(newState);

                dfa.setLexState(i, numDFAStates);

                dfa.setFinal(numDFAStates, containsFinal(newState));
                dfa.setPushback(numDFAStates, containsPushback(newState));
                dfa.setAction(numDFAStates, getAction(newState));

                numDFAStates++;
            }

            numDFAStates--;

            if (Options.DEBUG)
            {
                Out.debug("DFA start states are :" + Out.NL + dfaStates + Out.NL + Out.NL + "ordered :" + Out.NL + dfaVector);
            }

            currentDFAState = 0;

            StateSet           tempStateSet = NFA.tempStateSet;
            StateSetEnumerator states       = NFA.states;

            // will be reused
            newState = new StateSet(numStates);

            while (currentDFAState <= numDFAStates)
            {
                currentState = (StateSet)dfaVector[currentDFAState];

                for (char input = (char)0; input < numInput; input++)
                {
                    // newState = DFAEdge(currentState, input);

                    // inlining DFAEdge for performance:

                    // Out.debug("Calculating DFAEdge for state set "+currentState+" and input '"+input+"'");

                    tempStateSet.clear();
                    states.reset(currentState);
                    while (states.hasMoreElements())
                    {
                        tempStateSet.add(table[states.nextElement()][input]);
                    }

                    newState.copy(tempStateSet);

                    states.reset(tempStateSet);
                    while (states.hasMoreElements())
                    {
                        newState.add(epsilon[states.nextElement()]);
                    }

                    // Out.debug("DFAEdge is : "+newState);


                    if (newState.containsElements())
                    {
                        // Out.debug("DFAEdge for input "+(int)input+" and state set "+currentState+" is "+newState);

                        // Out.debug("Looking for state set "+newState);
                        Integer nextDFAState = (Integer)dfaStates[newState];

                        if (nextDFAState != null)
                        {
                            // Out.debug("FOUND!");
                            dfa.addTransition(currentDFAState, input, nextDFAState.intValue());
                        }
                        else
                        {
                            if (Options.progress)
                            {
                                Out.print(".");
                            }
                            // Out.debug("NOT FOUND!");
                            // Out.debug("Table was "+dfaStates);
                            numDFAStates++;

                            // make a new copy of newState to store in dfaStates
                            StateSet storeState = new StateSet(newState);

                            dfaStates[storeState] = new Integer(numDFAStates);
                            dfaVector.Add(storeState);

                            dfa.addTransition(currentDFAState, input, numDFAStates);
                            dfa.setFinal(numDFAStates, containsFinal(storeState));
                            dfa.setPushback(numDFAStates, containsPushback(storeState));
                            dfa.setAction(numDFAStates, getAction(storeState));
                        }
                    }
                }

                currentDFAState++;
            }

            if (Options.verbose)
            {
                Out.println("");
            }

            return(dfa);
        }
Example #11
0
        /**
         * Constructs an NFA for regExp such that the NFA has
         *
         *   exactly one start state,
         *   exactly one end state,
         *   no transitions leading out of the end state
         *   no transitions leading into the start state
         *
         * @param regExp the regular expression to construct the
         *        NFA for
         *
         * @return a pair of integers denoting the index of start
         *         and end state of the NFA.
         */
        public IntPair insertNFA(RegExp regExp)
        {
            IntPair nfa1, nfa2;
            int     start, end;
            RegExp2 r;

            if (Options.DEBUG)
            {
                Out.debug("Inserting RegExp : " + regExp);
            }

            if (regExp.isCharClass(macros))
            {
                start = numStates;
                end   = numStates + 1;

                ensureCapacity(end + 1);
                if (end + 1 > numStates)
                {
                    numStates = end + 1;
                }

                insertNFA(regExp, start, end);

                return(new IntPair(start, end));
            }

            switch (regExp.type)
            {
            case sym.BAR:

                r = (RegExp2)regExp;

                nfa1 = insertNFA(r.r1);
                nfa2 = insertNFA(r.r2);

                start = nfa2.end + 1;
                end   = nfa2.end + 2;

                addEpsilonTransition(start, nfa1.start);
                addEpsilonTransition(start, nfa2.start);
                addEpsilonTransition(nfa1.end, end);
                addEpsilonTransition(nfa2.end, end);

                return(new IntPair(start, end));

            case sym.CONCAT:

                r = (RegExp2)regExp;

                nfa1 = insertNFA(r.r1);
                nfa2 = insertNFA(r.r2);

                addEpsilonTransition(nfa1.end, nfa2.start);

                return(new IntPair(nfa1.start, nfa2.end));

            case sym.STAR:
                nfa1 = insertNFA((RegExp)((RegExp1)regExp).content);

                start = nfa1.end + 1;
                end   = nfa1.end + 2;

                addEpsilonTransition(nfa1.end, end);
                addEpsilonTransition(start, nfa1.start);

                addEpsilonTransition(start, end);
                addEpsilonTransition(nfa1.end, nfa1.start);

                return(new IntPair(start, end));

            case sym.PLUS:
                nfa1 = insertNFA((RegExp)((RegExp1)regExp).content);

                start = nfa1.end + 1;
                end   = nfa1.end + 2;

                addEpsilonTransition(nfa1.end, end);
                addEpsilonTransition(start, nfa1.start);

                addEpsilonTransition(nfa1.end, nfa1.start);

                return(new IntPair(start, end));

            case sym.QUESTION:
                nfa1 = insertNFA((RegExp)((RegExp1)regExp).content);

                addEpsilonTransition(nfa1.start, nfa1.end);

                return(new IntPair(nfa1.start, nfa1.end));

            case sym.BANG:
                return(complement(insertNFA((RegExp)((RegExp1)regExp).content)));

            case sym.TILDE:
                nfa1 = insertNFA((RegExp)((RegExp1)regExp).content);

                start = nfa1.end + 1;
                int s1 = start + 1;
                int s2 = s1 + 1;
                end = s2 + 1;

                for (int i = 0; i < numInput; i++)
                {
                    addTransition(s1, i, s1);
                    addTransition(s2, i, s2);
                }

                addEpsilonTransition(start, s1);
                addEpsilonTransition(s1, nfa1.start);
                addEpsilonTransition(nfa1.end, s2);
                addEpsilonTransition(s2, end);

                nfa1 = complement(new IntPair(start, end));
                nfa2 = insertNFA((RegExp)((RegExp1)regExp).content);

                addEpsilonTransition(nfa1.end, nfa2.start);

                return(new IntPair(nfa1.start, nfa2.end));

            case sym.STRING:
                return(insertStringNFA(false, (String)((RegExp1)regExp).content));

            case sym.STRING_I:
                return(insertStringNFA(true, (String)((RegExp1)regExp).content));

            case sym.MACROUSE:
                return(insertNFA(macros.getDefinition((String)((RegExp1)regExp).content)));
            }

            throw new Exception("Unknown expression type " + regExp.type + " in NFA construction");
        }