Example #1
0
        /**
         * Performs semantic analysis for all expressions.
         *
         * Currently: illegal lookahead check only
         * [fixme: more checks possible]
         *
         * @param rs   the reg exps to be checked
         * @param m    the macro table (in expanded form)
         * @param max  max character of the used charset (for negation)
         * @param f    the spec file containing the rules [fixme]
         */
        public static void check(RegExps rs, Macros m, char max, File f)
        {
            macros  = m;
            maxChar = max;

            bool errors = false;
            int  num    = rs.getNum();

            for (int i = 0; i < num; i++)
            {
                RegExp r = rs.getRegExp(i);
                RegExp l = rs.getLookAhead(i);

                if (!checkLookAhead(r, l))
                {
                    errors = true;
                    Out.error(f, ErrorMessages.LOOKAHEAD_ERROR, rs.getLine(i), -1);
                }
            }

            if (errors)
            {
                throw new GeneratorException();
            }
        }
 public void checkActions()
 {
     if (actions[actions.Count - 1] == null)
     {
         Out.error(ErrorMessages.NO_LAST_ACTION);
         throw new GeneratorException();
     }
 }
Example #3
0
 public void writeDot(File file)
 {
     try {
         StreamWriter writer = new StreamWriter(file);
         writer.WriteLine(dotFormat());
         writer.Close();
     }
     catch (IOException) {
         Out.error(ErrorMessages.FILE_WRITE, file);
         throw new GeneratorException();
     }
 }
Example #4
0
 /**
  * (Re)load the default skeleton. Looks in the current system class path.
  */
 public static void readDefault()
 {
     try
     {
         Assembly assembly = typeof(Skeleton).Assembly;
         Stream   stream   = assembly.GetManifestResourceStream("csflex.skeleton.default");
         readSkel(new StreamReader(stream));
     } catch {
         Out.error(ErrorMessages.SKEL_IO_ERROR_DEFAULT);
         throw new GeneratorException();
     }
 }
        /**
         * Reads an external skeleton file from a BufferedReader.
         *
         * @param  reader             the reader to read from (must be != null)
         * @throws IOException        if an IO error occurs
         * @throws GeneratorException if the number of skeleton sections does not match
         */
        public static void readSkel(TextReader reader)
        {
            isCSharpSkeleton        = false;
            notCSharpSkeletonWarned = false;

            ArrayList     lines   = new PrettyArrayList();
            StringBuilder section = new StringBuilder();

            String ln;

            while ((ln = reader.ReadLine()) != null)
            {
                if (ln.StartsWith("---")) //$NON-NLS-1$
                {
                    lines.Add(section.ToString());
                    section.Length = 0;
                }
                else
                {
                    section.Append(ln);
                    section.Append(NL);
                }
            }

            if (section.Length > 0)
            {
                lines.Add(section.ToString());
            }

            if (lines.Count != size)
            {
                if (lines.Count == size * 2)
                {
                    isCSharpSkeleton = true;
                }
                else
                {
                    Out.error(ErrorMessages.WRONG_SKELETON);
                    throw new GeneratorException();
                }
            }

            line = new String[lines.Count];
            for (int i = 0; i < lines.Count; i++)
            {
                line[i] = (String)lines[i];
            }
        }
Example #6
0
        /**
         * Set output directory
         *
         * @param d  the directory to write output files to
         */
        public static void setDir(File d)
        {
            if (d.isFile())
            {
                Out.error("Error: \"" + d + "\" is not a directory.");
                throw new GeneratorException();
            }

            if (!d.isDirectory() && !d.mkdirs())
            {
                Out.error("Error: couldn't create directory \"" + d + "\"");
                throw new GeneratorException();
            }

            directory = d;
        }
Example #7
0
        /**
         * Reads an external skeleton file for later use with this class.
         *
         * @param skeletonFile  the file to read (must be != null and readable)
         */
        public static void readSkelFile(string skeletonFile)
        {
            if (skeletonFile == null)
            {
                throw new ArgumentException("Skeleton file must not be null", "skeletonFile"); //$NON-NLS-1$
            }
            try
            {
                FileStream stream = new FileStream(skeletonFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                stream.Close();
            }
            catch
            {
                Out.error(ErrorMessages.CANNOT_READ_SKEL, skeletonFile.ToString());
                throw new GeneratorException();
            }

            Out.println(ErrorMessages.READING_SKEL, skeletonFile.ToString());

            StreamReader reader = null;

            try
            {
                reader = new StreamReader(skeletonFile, Encoding.UTF8, true);
                readSkel(reader);
            }
            catch (IOException)
            {
                Out.error(ErrorMessages.SKEL_IO_ERROR);
                throw new GeneratorException();
            }
            finally
            {
                if (reader != null)
                {
                    reader.Close();
                }
            }
        }
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
        /**
         * Implementation of Hopcroft's O(n log n) minimization algorithm, follows
         * description by D. Gries.
         *
         * Time: O(n log n)
         * Space: O(c n), size < 4*(5*c*n + 13*n + 3*c) byte
         */
        public void minimize()
        {
            int i, j;

            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;
            }

            // the algorithm needs the DFA to be total, so we add an error state 0,
            // and translate the rest of the states by +1
            int n = numStates + 1;

            // block information:
            // [0..n-1] stores which block a state belongs to,
            // [n..2*n-1] stores how many elements each block has
            int [] block = new int[2 * n];

            // implements a doubly linked list of states (these are the actual blocks)
            int [] b_forward  = new int[2 * n];
            int [] b_backward = new int[2 * n];

            // the last of the blocks currently in use (in [n..2*n-1])
            // (end of list marker, points to the last used block)
            int lastBlock = n; // at first we start with one empty block
            int b0        = n; // the first block

            // the circular doubly linked list L of pairs (B_i, c)
            // (B_i, c) in L iff l_forward[(B_i-n)*numInput+c] > 0 // numeric value of block 0 = n!
            int [] l_forward  = new int[n * numInput + 1];
            int [] l_backward = new int[n * numInput + 1];
            int    anchorL    = n * numInput; // list anchor

            // inverse of the transition table
            // if t = inv_delta[s][c] then { inv_delta_set[t], inv_delta_set[t+1], .. inv_delta_set[k] }
            // is the set of states, with inv_delta_set[k] = -1 and inv_delta_set[j] >= 0 for t <= j < k
            int [] [] inv_delta = new int[n][];
            for (int idx = 0; idx < inv_delta.Length; idx++)
            {
                inv_delta[idx] = new int[numInput];
            }
            int [] inv_delta_set = new int [2 * n * numInput];

            // twin stores two things:
            // twin[0]..twin[numSplit-1] is the list of blocks that have been split
            // twin[B_i] is the twin of block B_i
            int [] twin = new int[2 * n];
            int    numSplit;

            // SD[B_i] is the the number of states s in B_i with delta(s,a) in B_j
            // if SD[B_i] == block[B_i], there is no need to split
            int [] SD = new int[2 * n]; // [only SD[n..2*n-1] is used]


            // for fixed (B_j,a), the D[0]..D[numD-1] are the inv_delta(B_j,a)
            int [] D = new int[n];
            int    numD;


            // initialize inverse of transition table
            int lastDelta = 0;

            int [] inv_lists     = new int[n]; // holds a set of lists of states
            int [] inv_list_last = new int[n]; // the last element
            for (int c = 0; c < numInput; c++)
            {
                // clear "head" and "last element" pointers
                for (int s = 0; s < n; s++)
                {
                    inv_list_last[s] = -1;
                    inv_delta[s][c]  = -1;
                }

                // the error state has a transition for each character into itself
                inv_delta[0][c]  = 0;
                inv_list_last[0] = 0;

                // accumulate states of inverse delta into lists (inv_delta serves as head of list)
                for (int s = 1; s < n; s++)
                {
                    int t = table[s - 1][c] + 1;

                    if (inv_list_last[t] == -1) // if there are no elements in the list yet
                    {
                        inv_delta[t][c]  = s;   // mark t as first and last element
                        inv_list_last[t] = s;
                    }
                    else
                    {
                        inv_lists[inv_list_last[t]] = s; // link t into chain
                        inv_list_last[t]            = s; // and mark as last element
                    }
                }

                // now move them to inv_delta_set in sequential order,
                // and update inv_delta accordingly
                for (int s = 0; s < n; s++)
                {
                    int  i_    = inv_delta[s][c];  inv_delta[s][c] = lastDelta;
                    int  j_    = inv_list_last[s];
                    bool go_on = (i_ != -1);
                    while (go_on)
                    {
                        go_on = (i_ != j_);
                        inv_delta_set[lastDelta++] = i_;
                        i_ = inv_lists[i_];
                    }
                    inv_delta_set[lastDelta++] = -1;
                }
            } // of initialize inv_delta

            // printInvDelta(inv_delta, inv_delta_set);

            // initialize blocks

            // make b0 = {0}  where 0 = the additional error state
            b_forward[b0]  = 0;
            b_backward[b0] = 0;
            b_forward[0]   = b0;
            b_backward[0]  = b0;
            block[0]       = b0;
            block[b0]      = 1;

            for (int s = 1; s < n; s++)
            {
                // System.out.println("Checking state ["+(s-1)+"]");
                // search the blocks if it fits in somewhere
                // (fit in = same pushback behavior, same finalness, same lookahead behavior, same action)
                int  b     = b0 + 1; // no state can be equivalent to the error state
                bool found = false;
                while (!found && b <= lastBlock)
                {
                    // get some state out of the current block
                    int t = b_forward[b];
                    // System.out.println("  picking state ["+(t-1)+"]");

                    // check, if s could be equivalent with t
                    found = (isPushback[s - 1] == isPushback[t - 1]) && (isLookEnd[s - 1] == isLookEnd[t - 1]);
                    if (found)
                    {
                        if (isFinal[s - 1])
                        {
                            found = isFinal[t - 1] && action[s - 1].isEquiv(action[t - 1]);
                        }
                        else
                        {
                            found = !isFinal[t - 1];
                        }

                        if (found) // found -> add state s to block b
                        // System.out.println("Found! Adding to block "+(b-b0));
                        // update block information
                        {
                            block[s] = b;
                            block[b]++;

                            // chain in the new element
                            int last = b_backward[b];
                            b_forward[last] = s;
                            b_forward[s]    = b;
                            b_backward[b]   = s;
                            b_backward[s]   = last;
                        }
                    }

                    b++;
                }

                if (!found) // fits in nowhere -> create new block
                // System.out.println("not found, lastBlock = "+lastBlock);

                // update block information
                {
                    block[s] = b;
                    block[b]++;

                    // chain in the new element
                    b_forward[b]  = s;
                    b_forward[s]  = b;
                    b_backward[b] = s;
                    b_backward[s] = b;

                    lastBlock++;
                }
            } // of initialize blocks

            // printBlocks(block,b_forward,b_backward,lastBlock);

            // initialize worklist L
            // first, find the largest block B_max, then, all other (B_i,c) go into the list
            int B_max = b0;
            int B_i;

            for (B_i = b0 + 1; B_i <= lastBlock; B_i++)
            {
                if (block[B_max] < block[B_i])
                {
                    B_max = B_i;
                }
            }

            // L = empty
            l_forward[anchorL]  = anchorL;
            l_backward[anchorL] = anchorL;

            // set up the first list element
            if (B_max == b0)
            {
                B_i = b0 + 1;
            }
            else
            {
                B_i = b0;                      // there must be at least two blocks
            }
            int index = (B_i - b0) * numInput; // (B_i, 0)

            while (index < (B_i + 1 - b0) * numInput)
            {
                int last = l_backward[anchorL];
                l_forward[last]     = index;
                l_forward[index]    = anchorL;
                l_backward[index]   = last;
                l_backward[anchorL] = index;
                index++;
            }

            // now do the rest of L
            while (B_i <= lastBlock)
            {
                if (B_i != B_max)
                {
                    index = (B_i - b0) * numInput;
                    while (index < (B_i + 1 - b0) * numInput)
                    {
                        int last = l_backward[anchorL];
                        l_forward[last]     = index;
                        l_forward[index]    = anchorL;
                        l_backward[index]   = last;
                        l_backward[anchorL] = index;
                        index++;
                    }
                }
                B_i++;
            }
            // end of setup L

            // start of "real" algorithm
            // int step = 0;
            // System.out.println("max_steps = "+(n*numInput));
            // while L not empty
            while (l_forward[anchorL] != anchorL)
            {
                // System.out.println("step : "+(step++));
                // printL(l_forward, l_backward, anchorL);

                // pick and delete (B_j, a) in L:

                // pick
                int B_j_a = l_forward[anchorL];
                // delete
                l_forward[anchorL]             = l_forward[B_j_a];
                l_backward[l_forward[anchorL]] = anchorL;
                l_forward[B_j_a] = 0;
                // take B_j_a = (B_j-b0)*numInput+c apart into (B_j, a)
                int B_j = b0 + B_j_a / numInput;
                int a   = B_j_a % numInput;

                // printL(l_forward, l_backward, anchorL);

                // System.out.println("picked ("+B_j+","+a+")");
                // printL(l_forward, l_backward, anchorL);

                // determine splittings of all blocks wrt (B_j, a)
                // i.e. D = inv_delta(B_j,a)
                numD = 0;
                int s = b_forward[B_j];
                while (s != B_j)
                {
                    // System.out.println("splitting wrt. state "+s);
                    int t = inv_delta[s][a];
                    // System.out.println("inv_delta chunk "+t);
                    while (inv_delta_set[t] != -1)
                    {
                        // System.out.println("D+= state "+inv_delta_set[t]);
                        D[numD++] = inv_delta_set[t++];
                    }
                    s = b_forward[s];
                }

                // clear the twin list
                numSplit = 0;

                // System.out.println("splitting blocks according to D");

                // clear SD and twins (only those B_i that occur in D)
                for (int indexD = 0; indexD < numD; indexD++) // for each s in D
                {
                    s         = D[indexD];
                    B_i       = block[s];
                    SD[B_i]   = -1;
                    twin[B_i] = 0;
                }

                // count how many states of each B_i occuring in D go with a into B_j
                // Actually we only check, if *all* t in B_i go with a into B_j.
                // In this case SD[B_i] == block[B_i] will hold.
                for (int indexD = 0; indexD < numD; indexD++) // for each s in D
                {
                    s   = D[indexD];
                    B_i = block[s];

                    // only count, if we haven't checked this block already
                    if (SD[B_i] < 0)
                    {
                        SD[B_i] = 0;
                        int t = b_forward[B_i];
                        while (t != B_i && (t != 0 || block[0] == B_j) &&
                               (t == 0 || block[table[t - 1][a] + 1] == B_j))
                        {
                            SD[B_i]++;
                            t = b_forward[t];
                        }
                    }
                }

                // split each block according to D
                for (int indexD = 0; indexD < numD; indexD++) // for each s in D
                {
                    s   = D[indexD];
                    B_i = block[s];

                    // System.out.println("checking if block "+(B_i-b0)+" must be split because of state "+s);

                    if (SD[B_i] != block[B_i])
                    {
                        // System.out.println("state "+(s-1)+" must be moved");
                        int B_k = twin[B_i];
                        if (B_k == 0)
                        {
                            // no twin for B_i yet -> generate new block B_k, make it B_i's twin
                            B_k = ++lastBlock;
                            // System.out.println("creating block "+(B_k-n));
                            // printBlocks(block,b_forward,b_backward,lastBlock-1);
                            b_forward[B_k]  = B_k;
                            b_backward[B_k] = B_k;

                            twin[B_i] = B_k;

                            // mark B_i as split
                            twin[numSplit++] = B_i;
                        }
                        // move s from B_i to B_k

                        // remove s from B_i
                        b_forward[b_backward[s]] = b_forward[s];
                        b_backward[b_forward[s]] = b_backward[s];

                        // add s to B_k
                        int last = b_backward[B_k];
                        b_forward[last] = s;
                        b_forward[s]    = B_k;
                        b_backward[s]   = last;
                        b_backward[B_k] = s;

                        block[s] = B_k;
                        block[B_k]++;
                        block[B_i]--;

                        SD[B_i]--; // there is now one state less in B_i that goes with a into B_j
                        // printBlocks(block, b_forward, b_backward, lastBlock);
                        // System.out.println("finished move");
                    }
                } // of block splitting

                // printBlocks(block, b_forward, b_backward, lastBlock);

                // System.out.println("updating L");

                // update L
                for (int indexTwin = 0; indexTwin < numSplit; indexTwin++)
                {
                    B_i = twin[indexTwin];
                    int B_k = twin[B_i];
                    for (int c = 0; c < numInput; c++)
                    {
                        int B_i_c = (B_i - b0) * numInput + c;
                        int B_k_c = (B_k - b0) * numInput + c;
                        if (l_forward[B_i_c] > 0)
                        {
                            // (B_i,c) already in L --> put (B_k,c) in L
                            int last = l_backward[anchorL];
                            l_backward[anchorL] = B_k_c;
                            l_forward[last]     = B_k_c;
                            l_backward[B_k_c]   = last;
                            l_forward[B_k_c]    = anchorL;
                        }
                        else
                        {
                            // put the smaller block in L
                            if (block[B_i] <= block[B_k])
                            {
                                int last = l_backward[anchorL];
                                l_backward[anchorL] = B_i_c;
                                l_forward[last]     = B_i_c;
                                l_backward[B_i_c]   = last;
                                l_forward[B_i_c]    = anchorL;
                            }
                            else
                            {
                                int last = l_backward[anchorL];
                                l_backward[anchorL] = B_k_c;
                                l_forward[last]     = B_k_c;
                                l_backward[B_k_c]   = last;
                                l_forward[B_k_c]    = anchorL;
                            }
                        }
                    }
                }
            }

            // System.out.println("Result");
            // printBlocks(block,b_forward,b_backward,lastBlock);

            /*
             * System.out.println("Old minimization:");
             * boolean [] [] equiv = old_minimize();
             *
             * boolean error = false;
             * for (int i = 1; i < equiv.length; i++) {
             * for (int j = 0; j < equiv[i].length; j++) {
             *  if (equiv[i][j] != (block[i+1] == block[j+1])) {
             *    System.out.println("error: equiv["+i+"]["+j+"] = "+equiv[i][j]+
             *                       ", block["+i+"] = "+block[i+1]+", block["+j+"] = "+block[j]);
             *    error = true;
             *  }
             * }
             * }
             *
             * if (error) System.exit(1);
             * System.out.println("check");
             */

            // transform the transition table

            // trans[i] is the state j that will replace state i, i.e.
            // states i and j are equivalent
            int[] trans = new int [numStates];

            // kill[i] is true iff state i is redundant and can be removed
            bool[] kill = new bool [numStates];

            // move[i] is the amount line i has to be moved in the transition table
            // (because states j < i have been removed)
            int[] move = new int [numStates];

            // fill arrays trans[] and kill[] (in O(n))
            for (int b = b0 + 1; b <= lastBlock; b++) // b0 contains the error state
            // get the state with smallest value in current block
            {
                int s     = b_forward[b];
                int min_s = s; // there are no empty blocks!
                for (; s != b; s = b_forward[s])
                {
                    if (min_s > s)
                    {
                        min_s = s;
                    }
                }
                // now fill trans[] and kill[] for this block
                // (and translate states back to partial DFA)
                min_s--;
                for (s = b_forward[b] - 1; s != b - 1; s = b_forward[s + 1] - 1)
                {
                    trans[s] = min_s;
                    kill[s]  = s != min_s;
                }
            }

            // fill array move[] (in O(n))
            int amount = 0;

            for (int idx = 0; idx < numStates; idx++)
            {
                if (kill[idx])
                {
                    amount++;
                }
                else
                {
                    move[idx] = amount;
                }
            }

            // j is the index in the new transition table
            // the transition table is transformed in place (in O(c n))
            for (i = 0, j = 0; i < numStates; i++)
            {
                // we only copy lines that have not been removed
                if (!kill[i])
                {
                    // translate the target states
                    for (int c = 0; c < numInput; c++)
                    {
                        if (table[i][c] >= 0)
                        {
                            table[j][c]  = trans[table[i][c]];
                            table[j][c] -= move[table[j][c]];
                        }
                        else
                        {
                            table[j][c] = table[i][c];
                        }
                    }

                    isFinal[j]    = isFinal[i];
                    isPushback[j] = isPushback[i];
                    isLookEnd[j]  = isLookEnd[i];
                    action[j]     = action[i];

                    j++;
                }
            }

            numStates = j;

            // translate lexical states
            for (i = 0; i < lexState.Length; i++)
            {
                lexState[i]  = trans[lexState[i]];
                lexState[i] -= move[lexState[i]];
            }

            Out.println(numStates + " states in minimized DFA");
        }
Example #10
0
        public const String version = "1.4"; //$NON-NLS-1$

        /**
         * Generates a scanner for the specified input file.
         *
         * @param inputFile  a file containing a lexical specification
         *                   to generate a scanner for.
         */
        public static void generate(File inputFile)
        {
            Out.resetCounters();

            Timer totalTime = new Timer();
            Timer time      = new Timer();

            LexScan    scanner     = null;
            LexParse   parser      = null;
            TextReader inputReader = null;

            totalTime.start();

            try {
                Out.println(ErrorMessages.READING, inputFile.ToString());
                inputReader = new StreamReader(inputFile);
                scanner     = new LexScan(inputReader);
                scanner.setFile(inputFile);
                parser = new LexParse(scanner);
            }
            catch (FileNotFoundException) {
                Out.error(ErrorMessages.CANNOT_OPEN, inputFile.ToString());
                throw new GeneratorException();
            }

            try {
                NFA nfa = (NFA)parser.parse().value;

                Out.checkErrors();

                if (Options.dump)
                {
                    Out.dump(ErrorMessages.get(ErrorMessages.NFA_IS) +
                             Out.NL + nfa + Out.NL);
                }

                if (Options.dot)
                {
                    nfa.writeDot(Emitter.normalize("nfa.dot", null)); //$NON-NLS-1$
                }
                Out.println(ErrorMessages.NFA_STATES, nfa.numStates);

                time.start();
                DFA dfa = nfa.getDFA();
                time.stop();
                Out.time(ErrorMessages.DFA_TOOK, time);

                dfa.checkActions(scanner, parser);

                nfa = null;

                if (Options.dump)
                {
                    Out.dump(ErrorMessages.get(ErrorMessages.DFA_IS) +
                             Out.NL + dfa + Out.NL);
                }

                if (Options.dot)
                {
                    dfa.writeDot(Emitter.normalize("dfa-big.dot", null)); //$NON-NLS-1$
                }
                time.start();
                dfa.minimize();
                time.stop();

                Out.time(ErrorMessages.MIN_TOOK, time);

                if (Options.dump)
                {
                    Out.dump(ErrorMessages.get(ErrorMessages.MIN_DFA_IS) +
                             Out.NL + dfa);
                }

                if (Options.dot)
                {
                    dfa.writeDot(Emitter.normalize("dfa-min.dot", null)); //$NON-NLS-1$
                }
                time.start();

                Emitter e = new Emitter(inputFile, parser, dfa);
                e.emit();

                time.stop();

                Out.time(ErrorMessages.WRITE_TOOK, time);

                totalTime.stop();

                Out.time(ErrorMessages.TOTAL_TIME, totalTime);
            }
            catch (ScannerException e) {
                Out.error(e.file, e.message, e.line, e.column);
                throw new GeneratorException();
            }
            catch (MacroException e) {
                Out.error(e.Message);
                throw new GeneratorException();
            }
            catch (IOException e) {
                Out.error(ErrorMessages.IO_ERROR, e.ToString());
                throw new GeneratorException();
            }
            catch (OutOfMemoryException) {
                Out.error(ErrorMessages.OUT_OF_MEMORY);
                throw new GeneratorException();
            }
            catch (GeneratorException) {
                throw new GeneratorException();
            }
            catch (Exception e) {
                Out.error(e.ToString());
                throw new GeneratorException();
            }
        }
Example #11
0
        public static ArrayList parseOptions(String[] argv)
        {
            ArrayList files = new PrettyArrayList();

            for (int i = 0; i < argv.Length; i++)
            {
                if ((argv[i] == "-d") || (argv[i] == "--outdir")) //$NON-NLS-1$ //$NON-NLS-2$
                {
                    if (++i >= argv.Length)
                    {
                        Out.error(ErrorMessages.NO_DIRECTORY);
                        throw new GeneratorException();
                    }
                    Options.setDir(argv[i]);
                    continue;
                }

                if ((argv[i] == "--skel") || (argv[i] == "-skel")) //$NON-NLS-1$ //$NON-NLS-2$
                {
                    if (++i >= argv.Length)
                    {
                        Out.error(ErrorMessages.NO_SKEL_FILE);
                        throw new GeneratorException();
                    }

                    Options.setSkeleton(new File(argv[i]));
                    continue;
                }

                if ((argv[i] == "--nested-default-skeleton") || (argv[i] == "-nested"))
                {
                    Options.setSkeleton(new File("<nested>"));
                    continue;
                }

                if ((argv[i] == "-jlex") || (argv[i] == "--jlex")) //$NON-NLS-1$ //$NON-NLS-2$
                {
                    Options.jlex = true;
                    continue;
                }

                if ((argv[i] == "-v") || (argv[i] == "--verbose") || (argv[i] == "-verbose")) //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
                {
                    Options.verbose  = true;
                    Options.progress = true;
                    continue;
                }

                if ((argv[i] == "-q") || (argv[i] == "--quiet") || (argv[i] == "-quiet")) //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
                {
                    Options.verbose  = false;
                    Options.progress = false;
                    continue;
                }

                if ((argv[i] == "--dump") || (argv[i] == "-dump")) //$NON-NLS-1$ //$NON-NLS-2$
                {
                    Options.dump = true;
                    continue;
                }

                if ((argv[i] == "--time") || (argv[i] == "-time")) //$NON-NLS-1$ //$NON-NLS-2$
                {
                    Options.time = true;
                    continue;
                }

                if ((argv[i] == "--version") || (argv[i] == "-version")) //$NON-NLS-1$ //$NON-NLS-2$
                {
                    Out.println(ErrorMessages.THIS_IS_CSFLEX, version);
                    throw new SilentExit();
                }

                if ((argv[i] == "--dot") || (argv[i] == "-dot")) //$NON-NLS-1$ //$NON-NLS-2$
                {
                    Options.dot = true;
                    continue;
                }

                if ((argv[i] == "--help") || (argv[i] == "-h") || (argv[i] == "/h")) //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
                {
                    printUsage();
                    throw new SilentExit();
                }

                if ((argv[i] == "--info") || (argv[i] == "-info")) //$NON-NLS-1$ //$NON-NLS-2$
                {
                    Out.printSystemInfo();
                    throw new SilentExit();
                }

                if ((argv[i] == "--nomin") || (argv[i] == "-nomin")) //$NON-NLS-1$ //$NON-NLS-2$
                {
                    Options.no_minimize = true;
                    continue;
                }

                if ((argv[i] == "--pack") || (argv[i] == "-pack")) //$NON-NLS-1$ //$NON-NLS-2$
                {
                    Options.gen_method = Options.PACK;
                    continue;
                }

                if ((argv[i] == "--table") || (argv[i] == "-table")) //$NON-NLS-1$ //$NON-NLS-2$
                {
                    Options.gen_method = Options.TABLE;
                    continue;
                }

                if ((argv[i] == "--switch") || (argv[i] == "-switch")) //$NON-NLS-1$ //$NON-NLS-2$
                {
                    Options.gen_method = Options.SWITCH;
                    continue;
                }

                if ((argv[i] == "--nobak") || (argv[i] == "-nobak")) //$NON-NLS-1$ //$NON-NLS-2$
                {
                    Options.no_backup = true;
                    continue;
                }

                if ((argv[i] == "--csharp") || (argv[i] == "-cs"))
                {
                    Options.emit_csharp = true;
                    continue;
                }

                if (argv[i].StartsWith("-")) //$NON-NLS-1$
                {
                    Out.error(ErrorMessages.UNKNOWN_COMMANDLINE, argv[i]);
                    printUsage();
                    throw new SilentExit();
                }

                // if argv[i] is not an option, try to read it as file
                File f = new File(argv[i]);
                if (f.isFile() && f.canRead())
                {
                    files.Add(f);
                }
                else
                {
                    Out.error("Sorry, couldn't open \"" + f + "\""); //$NON-NLS-2$
                    throw new GeneratorException();
                }
            }

            return(files);
        }