⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 macrotable.java

📁 外国人写的c#语法解析器
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
      if (result == null)
        return null;
      else
        return result.toString();
    }

    //----------------------------------------------------------------------------------------------

    /**
     * Determines if this macro has got replacement text or is just a defined symbol.
     * 
     * @return <b>true</b> if there is replacement text, <b>false</b> if it is only a symbol.
     */
    public boolean isEmpty()
    {
      return (substitution != null && substitution.length() > 0);
    }

    //----------------------------------------------------------------------------------------------

  }

  //------------------------------------------------------------------------------------------------

  /**
   * This private class serves as convenience class for setting up a tokenizer.
   */
  private class MacroTokenizer
  {
    private Reader reader;
    private StreamTokenizer tokenizer;
    
    //----------------------------------------------------------------------------------------------

    /**
     * Constructor for the tokenizer that takes a string as input.
     * 
     * @param input The input.
     * @param numberSignSeparate Determines if number signs (#) are treated separately or as part
     *                            of an identifier.
     */
    public MacroTokenizer(String input, boolean numberSignSeparate)
    {
      reader = new StringReader(input);
      tokenizer = new StreamTokenizer(reader);
      tokenizer.resetSyntax();
      tokenizer.lowerCaseMode(false);
      tokenizer.slashSlashComments(true);
      tokenizer.slashStarComments(true);
      tokenizer.wordChars('a', 'z');
      tokenizer.wordChars('A', 'Z');
      tokenizer.wordChars('_', '_');
      tokenizer.wordChars('0', '9');

      // Add the number sign as word char too. In our context it can only appear as part of
      // a preprocessor definition, which never can be a macro.
      if (!numberSignSeparate)
        tokenizer.wordChars('#', '#');
    }

    //----------------------------------------------------------------------------------------------

    /**
     * Scans the characters between two quote chars and returns them (without the quotes).
     * 
     * @param quoteChar The character to use for end recognition.
     * @return The scanned string literal.
     */
    private String readString(char quoteChar)
    {
      StringBuffer buffer = new StringBuffer();
      boolean skipNext = false;
      do
      {
        char c = 0;
        try
        {
          c = (char)reader.read();
        }
        catch (IOException e)
        {
          e.printStackTrace();
        }
        if (c == '\uFFFF')
          break;
        if (skipNext)
        {
          skipNext = false;
          buffer.append(c);
          continue;
        }
        if (c == '\\')
          skipNext = true;
        else
          if (c == quoteChar)
            break;
        buffer.append(c);
      }
      while (true);
      
      return buffer.toString();
    }

    //----------------------------------------------------------------------------------------------

    /**
     * This method extracts text between two parentheses (also with nesting) and must only be
     * called if the current token is an opening parenthesis. In this process no token retrieval
     * takes place but instead characters are read directly from the input.
     * 
     * @return The text between the parentheses.
     */
    public String getInnerText()
    {
      int level = 1;
      StringBuffer buffer = new StringBuffer();
      do
      {
        char c = 0;
        try
        {
          c = (char) reader.read();
        }
        catch (IOException e)
        {
          // Since we are reading from a string there can never be an IOException.
          // However rules are to have code for the exception, regardless of whether it appears or not.
          e.printStackTrace();
        }
        if (c == '\uFFFF')
          reportError("Unexpected end of input.");
        
        if (c == '(')
          level++;
        else
          if (c == ')')
            level--;
        // The level tracker becomes 0 when the end of the list was found.
        if (level == 0)
          break;
        buffer.append(c);
      }
      while (true);

      return buffer.toString();
    }
    
    //----------------------------------------------------------------------------------------------

    /**
     * Returns the current token as numeric value. This is only valid if the current token
     * is TT_NUMERAL.
     * 
     * @return The numeric value.
     */
    public double getNumericValue()
    {
      return tokenizer.nval;
    }

    //----------------------------------------------------------------------------------------------

    /**
     * Reads from the current input position up to count characters without tokenizing them and
     * returns the substring. Escape sequences are converted, too.
     * 
     * @param count The number of characters to read. This can also be a very high value to indicate
     *               that everything remaining on the input should be returned.
     * @return The substring with a length of either <b>count</b> or the remaining number of input
     *          characters, whichever is smaller.
     */
    public String getRawInput(int count)
    {
      StringBuffer buffer = new StringBuffer();
      while (count > 0)
      {
        char c = 0;
        try
        {
          c = (char) reader.read();
          
          // Convert escape sequence.
          if (c == '\\')
          {
            c = (char) reader.read();
            if(c == 'u')
            {
              // Read the xxxx.
              int value = 0;
              for (int i = 0; i < 4; i++)
              {
                c = (char) reader.read();
                switch (c)
                {
                  case '0': case '1': case '2': case '3': case '4':case '5':
                  case '6': case '7': case '8': case '9':
                  {
                    value = (value << 4) + c - '0';
                    break;
                  }
                  case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
                  {
                    value = (value << 4) + 10 + c - 'a';
                    break;
                  }
                  case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
                  {
                    value = (value << 4) + 10 + c - 'A';
                    break;
                  }
                  default:
                  {
                    throw new IllegalArgumentException("Malformed \\uxxxx encoding.");
                  }
                }
              }
              c = (char) value;
            }
            else
            {
              switch (c)
              {
                case 'a':
                {
                  c = 0x7;
                  break;
                }
                case 'b':
                {
                  c = '\b';
                  break;
                }
                case 'f':
                {
                  c = 0xC;
                  break;
                }
                case 'n':
                {
                  c = '\n';
                  break;
                }
                case 'r':
                {
                  c = '\r';
                  break;
                }
                case 't':
                {
                  c = '\t';
                  break;
                }
                case 'v':
                {
                  c = 0xB;
                  break;
                }
              }
            }
          }
        }
        catch (IOException e)
        {
          e.printStackTrace();
        }
        if (c == '\uFFFF')
          break;
        buffer.append(c);
      }
      return buffer.toString();
    }
    
    //----------------------------------------------------------------------------------------------

    /**
     * Returns the current token as string value. If the current token is a quote char then
     * the text included in the quotes is returned instead.
     * 
     * @return The string value.
     */
    public String getStringValue()
    {
      String result = "";
      switch (tokenizer.ttype)
      {
        case StreamTokenizer.TT_WORD:
        {
          result = tokenizer.sval;
          break;
        }
        case '"':
        {
          // Note: we cannot use the built-in feature of StreamTokenizer for strings as it
          //       tries to be too smart and converts all escape sequences to characters.
          //       This conflicts however with the following parser stage. Hence we do a raw scan
          //       on the underlying input stream.
          result = readString('"');
          break;
        }
        case '\'':
        {
          // See note for double quote case.
          result = readString('\'');
          break;
        }
      }
      return result;
    }

    //----------------------------------------------------------------------------------------------

    /**
     * Returns the next token from the internal tokenizer.
     * 
     * @return The next token.
     */
    public int nextToken()
    {
      try
      {
        return tokenizer.nextToken();
      }
      catch (IOException e)
      {
        // Since we are reading from a string there can never be an IOException.
        // However rules are to have code for the exception, regardless of whether it appears or not.
        e.printStackTrace();
        return StreamTokenizer.TT_EOF;
      }
    }

    //----------------------------------------------------------------------------------------------

    /**
     * Helper method to undo the last nextToken() call.
     */
    public void pushBack()
    {
      tokenizer.pushBack();
    }

    //----------------------------------------------------------------------------------------------

  }

  //------------------------------------------------------------------------------------------------

  protected void doEvent(int event, String message)
  {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -