`

采用JAVACC分析运算表达式

阅读更多

      上一篇文章通过分割字符串来进行表达式运算,感觉灵活性太差,比如要添加对变量的支持,需要修改很多地方。下边介绍采用javacc对运算表达式进行语义分析。---JavaCC主要是通过配置文件(xx.jj)生成分析代码的框架。

       ExpressionParser.jj配置文件:

---支持变量x、函数(sin,cos...)、简洁乘法(如 3sin(x) 表示3乘以sin(x))

 /**
 *分析计算公式
 * Saber
 */
 options
 {
   IGNORE_CASE=true;//忽略大小写
   STATIC =false;
 }
 
PARSER_BEGIN(ExpressionParser)
package myexample;
/** New line translator. */
public class ExpressionParser
{
  private  static double  x;
  public ExpressionParser(String expression)
  {
    this(new java.io.StringReader(expression));
  } 
   public ExpressionParser(String expression,double x)
  {
    this(new java.io.StringReader(expression));
    this.x=x;
  }  
  /** Main entry point. */
  public static void main(String args []) throws ParseException
  {
    ExpressionParser parser = new ExpressionParser(new java.io.StringReader("sin(3.15/2)"));
    System.out.println("解析结果="+parser.parse());

  }
}

PARSER_END(ExpressionParser)

SKIP :
{
  " "
| "\t"
| "\n"
| "\r"
}

TOKEN :
{
 /*计算符号*/
 < PLUS     : "+" >
| < MINUS   : "-" >
| < TIMES   : "*" >
| < DIVIDE  : "/" >
}
TOKEN : { < NUMBER : <DIGITS> | <DIGITS> "." <DIGITS> | <DIGITS>"." | "."<DIGITS> > }
TOKEN : { < #DIGITS : (["0"-"9"])+ > }
TOKEN : { < OPEN_PAR : "(" > |< CLOSE_PAR:")" >}
/*次方*/
TOKEN : { < POW_PAR : "^" > }
TOKEN : {
  /*函数*/
  < ABS    : "abs" >
| < SIN    : "sin" >
| < COS    : "cos" >
| < LOG    : "log" >
| < LOG10  : "log10" >
| < SQRT   : "sqrt" >
| < TAN    : "tan" >
| < POW    : "pow" >
}
TOKEN:{< X :"x" >/**变量**/}

/** 解析表达式 */
 double parse() :
{
  Token t;
  double  result=0;
  double  i=0;
}
{
  result=timesAndDivide()
  (
    < PLUS >
    i=timesAndDivide()
    {
      result+=i;
    }
| < MINUS >
 i=timesAndDivide()
    {
      result-=i;
    }
  )*
  
  {
    return result;
  }
}

/**基本运算单元**/
double  primary():
{
  Token t;
  double d;
}
{
 d=doNumber()
 {
 return d;
}
|d=calculatorPar()
{
 return d;
}
| < MINUS >d=primary()
{
return d;
}
| d=doFunction()
{
return d;
}
}

/**乘法运算**/
double  timesAndDivide():
{
 double  result=0;
 double   i=0;
}
{
 result=primary()
 (
   < TIMES >
   i=primary()
   {
    result*=i;
   }
| < DIVIDE >
i=primary()
   {
    result/=i;
   }
)*
 {
   return result;
 }

}
/**函数计算**/
double doFunction():
{
  double arg=0;
}
{
  < SIN > arg=calculatorPar()
  {
      return Math.sin(arg);
  }
| < COS >
arg=calculatorPar()
  {
      return Math.cos(arg);
  }

}
/**
* 遇到数字,有4种情况:
* a. 数字后紧跟着圆弧,如3(3-2),标识3乘以(3-2)
* b. 数字后是函数,如3sin(3.14),表示3乘以sin(3.14)
* c. 数字后是变量X,如3X,表示3乘以X变量
* d. 其他情况,则直接返回当前数字

*/
double doNumber():
{
  Token t;
  double d;
  double result;
}
{
  result= getNumber()
  (
   d=calculatorPar()
   {
    result=d*result;
   }
 | d=doFunction()
 {
  result=d*result;
 }
   )*
   {
    return result;
   }
{
   return result;
}
}
/**
 * 如果是数字则直接返回数字,否则,是变量则返回变量的次方
**/
double getNumber():
{ Token t;
  double result=1;
}
{
   t= < NUMBER >
  {
   result= Double.parseDouble(t.image);
  }
(
  
 < X >
 {
  result*=x;
 }
)*
{
return result;
}|
(  
 < X >
 {
  result*=x;
 }
)*
{
return result;
}
}

/*计算圆弧内的表达式*/
double calculatorPar():
{
double d;
}
{
< OPEN_PAR >d=parse()< CLOSE_PAR >
{
 return d;
}
}

 

分享到:
评论

相关推荐

    javacc四则运算表达式计算器

    本程序实现一个四则混合运算,用户只需要输入四则混合运算表达式,程序自动计算, 可以一次计算一个表达式,也可以批量计算多行表达式,而且适合商业计算精度要求。 由于该程序依赖一个清屏功能cls.dll,使用32位win7...

    javacc语法分析.zip

    例如,我们可以定义表达式文法,处理算术运算、比较操作等。 3. **词法分析**:JavaCC会根据用户定义的规则生成词法分析器,识别输入文本中的单词(Token)。这通常涉及到正则表达式的使用,用来匹配不同类型的词汇...

    java 写的 用优先函数分析 数学表达式的程序

    首先,我们需要理解什么是数学表达式分析。在计算机科学中,解析数学表达式通常涉及到词法分析和语法分析两个步骤。词法分析是将输入的字符流转化为有意义的词法单元(token),例如数字、运算符等。语法分析则...

    表达式计算器(java)

    - **编译器构造工具**:如ANTLR或JavaCC,这些工具可以帮助生成解析器和词法分析器。 为了调试和优化代码,开发者可能使用了JUnit等单元测试框架来编写测试用例,确保计算器在不同输入下的行为符合预期。 总的来说...

    javacc构造编译器的方法

    本文首先简要介绍了语法分析器自动生成的原理,并重点介绍了一个由Sun公司开发的编译器自动生成工具——JavaCC,以及如何利用JavaCC来构造编译器。 #### 二、编译器自动生成原理 编译器是计算机应用中最常用的工具...

    Test.rar 使用Javacc编写的简易计算器

    JavaCC,全称为Java Compiler Compiler,是一款强大的解析器生成器,用于构建语法分析器和词法分析器。它根据用户定义的语法规则生成Java源代码,这些源代码可以读取、解析符合规则的输入,比如编程语言、数学表达式...

    JAVACC构造编译器

    例如,你可以定义一个简单的算术表达式文法,处理加减乘除运算。 ```jj S ::= E END E ::= E "+" T | E "-" T | T T ::= T "*" F | T "/" F | F F ::= NUMBER END ::= "\n" NUMBER ::= DIGIT ::= "0" | "1" | ... ...

    使用Javacc做的解释器(超详细)

    JavaCC,全称为Java Compiler Compiler,是一款强大的工具,用于生成词法分析器和语法解析器。它是用Java编写的,可以生成符合Java语言规范的解析器,广泛应用于编译器设计、解释器构建以及XML、SQL等语言的解析。在...

    Java数学表达式计算(Expression Evaluator)

    词法分析是将输入的数学表达式分解为一个个符号(token),而语法分析则是根据这些符号构建抽象语法树(AST)。一旦构建了AST,就可以进行计算了。这种方式虽然复杂,但可以灵活地控制表达式的处理逻辑,比如添加...

    Generating Parsers with JavaCC-Centennial

    例如,你可以定义一个表达式文法,其中包含加减乘除等操作符,以及括号来控制运算的优先级。 JavaCC生成的解析器使用递归下降解析技术,这是一种高效的解析方法,特别适合处理上下文无关文法。解析器会逐个读取输入...

    javacc中文开发案例

    本例中的简单计算器程序展示了如何利用JavaCC来定义语法规则并实现基本的数学运算。无论是对于想要深入了解编译器工作原理的学习者,还是希望创建自己专属语言的开发者来说,JavaCC都是一个不可或缺的工具。

    Java实现计算字符串表达式

    2. **处理运算符优先级**:确保正确的运算顺序,比如遵循BODMAS规则(括号、指数、除法和乘法、加法和减法)。可以使用栈数据结构来处理运算符的优先级。 3. **计算值**:遍历AST,对每个节点进行相应的操作,如...

    哈工大威海语法分析实验

    这个文法涵盖了基本的算术运算,包括加法和乘法,并且支持嵌套的表达式。例如,"2 + 3 * x" 这样的表达式可以通过这些规则进行解析。 词法分析,或称扫描,是编译器的第一步。它将源代码分解成一个个被称为“记号”...

    java速算24游戏(代设计文档)

    - **用户界面**:程序应包含一个友好的用户界面,展示当前的数字和玩家的操作历史,同时提供输入框供玩家输入运算表达式。 - **游戏逻辑**:这部分负责验证用户输入的运算表达式是否正确,以及生成新的随机数字。 ...

    JAVA版的JAVA词法分析器

    这个JAVA版的词法分析器可能是基于某种解析技术实现的,例如使用正则表达式或者专门的词法分析生成器如ANTLR、JFlex或JavaCC。开发者可能已经对其进行了微调,以便在Eclipse环境中可以直接打开和运行,这意味着它...

    杭电编译原理实验,黄孝喜老师实验课

    学生需要熟练掌握正则表达式的运算规则,以及如何将其转换为有限状态自动机。 4. **前后缀表达式和中缀表达式**:编译原理中常讨论的计算表达式的方式,前缀和后缀表达式(也称波兰表示法和逆波兰表示法)没有括号...

    ExpreBrowser:表达式浏览器

    2. **数学运算符优先级与结合性**:为了正确计算表达式,程序需要理解运算符的优先级(如乘法先于加法)和结合性(如乘法是左结合,即a * b * c 等同于 (a * b) * c)。这需要在解析过程中正确处理这些规则。 3. **...

    C-minus-minus解释器构造

    JAVACC通过定义词法和语法规范(通常以JavaCC语法文件JJT格式提供),自动生成词法分析器(Tokenizer)和语法分析器(Parser)。 在构建C-减减解释器的过程中,我们首先要定义C-减减的语言语法。这包括标识符、常量...

Global site tag (gtag.js) - Google Analytics