예제 #1
0
        /**
         * Expands the specified macro by replacing each macro usage
         * with the stored definition.
         *
         * @param name        the name of the macro to expand (for detecting cycles)
         * @param definition  the definition of the macro to expand
         *
         * @return the expanded definition of the macro.
         *
         * @throws MacroException when an error (such as a cyclic definition)
         *                              occurs during expansion
         */
        private RegExp expandMacro(String name, RegExp definition)
        {
#if DEBUG_TRACE
            log.WriteLine("expandMacro(String name = \"{0}\", RegExp definition = {1})", name, definition);
#endif // DEBUG_TRACE

            // Out.print("checking macro "+name);
            // Out.print("definition is "+definition);

            switch (definition.type)
            {
            case sym.BAR:
            case sym.CONCAT:
                RegExp2 binary = (RegExp2)definition;
                binary.r1 = expandMacro(name, binary.r1);
                binary.r2 = expandMacro(name, binary.r2);
                return(definition);

            case sym.STAR:
            case sym.PLUS:
            case sym.QUESTION:
            case sym.BANG:
            case sym.TILDE:
                RegExp1 unary = (RegExp1)definition;
                unary.content = expandMacro(name, (RegExp)unary.content);
                return(definition);

            case sym.MACROUSE:
                String usename = (String)((RegExp1)definition).content;

                if (name.Equals(usename))
                {
                    throw new MacroException(ErrorMessages.get(ErrorMessages.MACRO_CYCLE, name));
                }

                RegExp usedef = getDefinition(usename);

                if (usedef == null)
                {
                    throw new MacroException(ErrorMessages.get(ErrorMessages.MACRO_DEF_MISSING, usename, name));
                }

                markUsed(usename);

                return(expandMacro(name, usedef));

            case sym.STRING:
            case sym.STRING_I:
            case sym.CHAR:
            case sym.CHAR_I:
            case sym.CCLASS:
            case sym.CCLASSNOT:
                return(definition);

            default:
                throw new MacroException("unknown expression type " + definition.type + " in macro expansion"); //$NON-NLS-1$ //$NON-NLS-2$
            }
        }
예제 #2
0
        /**
         * Constructs a two state NFA for char class regexps,
         * 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
         *
         * Assumes that regExp.isCharClass(macros) == true
         *
         * @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.
         */
        private void insertNFA(RegExp regExp, int start, int end)
        {
            switch (regExp.type)
            {
            case sym.BAR:
                RegExp2 r = (RegExp2)regExp;
                insertNFA(r.r1, start, end);
                insertNFA(r.r2, start, end);
                return;

            case sym.CCLASS:
                insertClassNFA((ArrayList)((RegExp1)regExp).content, start, end);
                return;

            case sym.CCLASSNOT:
                insertNotClassNFA((ArrayList)((RegExp1)regExp).content, start, end);
                return;

            case sym.CHAR:
                insertLetterNFA(
                    false, (char)((RegExp1)regExp).content,
                    start, end);
                return;

            case sym.CHAR_I:
                insertLetterNFA(
                    true, (char)((RegExp1)regExp).content,
                    start, end);
                return;

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

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