示例#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) throws MacroException {

    // 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
  /**
   * 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;
    FileReader inputReader = null;

    totalTime.start();

    try {
      Out.println(ErrorMessages.READING, inputFile.toString());
      inputReader = new FileReader(inputFile);
      scanner = new LexScan(inputReader);
      scanner.setFile(inputFile);
      parser = new LexParse(scanner);
    } catch (FileNotFoundException e) {
      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$

      Out.checkErrors();

      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.getMessage());
      throw new GeneratorException();
    } catch (IOException e) {
      Out.error(ErrorMessages.IO_ERROR, e.toString());
      throw new GeneratorException();
    } catch (OutOfMemoryError e) {
      Out.error(ErrorMessages.OUT_OF_MEMORY);
      throw new GeneratorException();
    } catch (GeneratorException e) {
      throw new GeneratorException();
    } catch (Exception e) {
      e.printStackTrace();
      throw new GeneratorException();
    }
  }