有一个现成的,非常好用:JavaCC(JavaCC Java Compiler Compiler),纯JAVA的词法分析生成器,功能十分强大,可以用来编写编译器的。
可以免费下载使用:http://www.webgain.com/products/java_cc/

解决方案 »

  1.   

    JavaCC会根据你给出的EBNF描述,自动生成词法分析程序和语法分析程序。====================
    第一步,你要用EBNF描述出你的语法形式,比如expr    :=    number 
          |    expr '+' expr 
          |    expr '-' expr 
          |    expr '*' expr 
          |    expr '/' expr 
          |    '(' expr ')'
          |   - expr
    number    :=    digit+ ('.' digit+)?
    digit     :=    '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
    ====================
    第二步,要将EBNF转译成JavaCC约定的格式,比如options
    {
        LOOKAHEAD=2;
    }PARSER_BEGIN(Calculator)public class Calculator
    {
        public static void main(String args[]) throws ParseException 
        {
            Calculator parser = new Calculator(System.in);
            while (true)
            {
                parser.parseOneLine();
            }
        }
    }PARSER_END(Calculator)SKIP :
    {
        " "
    |   "\r"
    |   "\t"
    }TOKEN:
    {
        < NUMBER: (<DIGIT>)+ ( "." (<DIGIT>)+ )? >
    |   < DIGIT: ["0"-"9"] >
    |   < EOL: "\n" >
    }void parseOneLine():
    {
        double a;
    }
    {
        a=expr() <EOL>      { System.out.println(a); }
      | <EOL>
      | <EOF>               { System.exit(-1); }
    }double expr():
    {
        double a;
        double b;
    }
    {
        a=term()
        (
            "+" b=expr()    { a += b; }
        |   "-" b=expr()    { a -= b; }
        )*
                            { return a; }
    }double term():
    {
        double a;
        double b;
    }
    {
        a=unary()
        (
            "*" b=term()    { a *= b; }
        |   "/" b=term()    { a /= b; }
        )*
                            { return a; }
    }double unary():
    {
        double a;
    }
    {
        "-" a=element()     { return -a; }
    |   a=element()         { return a; }
    }double element():
    {
        Token t;
        double a;
    }
    {
        t=<NUMBER>          { return Double.parseDouble(t.toString()); }
    |   "(" a=expr() ")"    { return a; }
    }
    注意看,里面有测试用的代码。:)
    将其保存为一个文件,后缀为*.jj,比如ABC.jj。
    ====================
    第三步,用JavaCC将*.jj文件“编译”成java程序javacc ABC.jjJavaCC会自动成生一系列的文件
    TokenMgrError.java
    ParseException.java
    Token.java
    ASCII_CharStream.java
    ABC.java
    ABCConstants.java
    ABCTokenManager.java
    ====================
    第四步,编译这些源文件,然后执行ABC.class。javac *.java
    java ABC 一切OK。