[引]构造文法时表达式中算符优先级的问题

1.描述

    由于要做一个万年历黄道吉日的推算,故考虑使用递归下降文法,以此为原型,设计了一个文法,之后再发,顺便整理了这篇文章。       

文法用于描述一种语言,语言中包含多个句子,句子又是由表达式组成的。多个原子表达式(不可再分的表达式,比如:a+b,c*d,-a等)和操作符或者括号一起又可以组成复合表达式(比如:a+b*c,a*(b+c)等)。在书写表达式文法时需要注意算符优先级问题,比如:四则运算中要优先计算乘除,然后才是加减,而被括号括起的表达式具有更高的优先级。解决优先级问题可以采取从优先级低的算符到优先级高的算符的顺序构造文法规则,由于括号相对于操作符具有更高的优先级,所以由括号括起的复合表达式可以作为原子表达式处理。下面拿四则运算举例说明:

expr : expr ‘+‘ term
     | expr ‘-‘ term
     | term
term : term ‘*‘ factor
     | term ‘/‘ factor
     | factor
factor : NUMBER
       | ‘(‘ expr ‘)‘

        expr和term都是复合表达式。expr就是表达式的起始规则,处理+和-操作符以及不含+和-的情况。term用于表示*和/操作符以及不含*和/的情况。factor就是原子表达式,直接返回词法单元或者是由括号括起来的复合表达式。

2.比较运算符演练

     下面为比较运算构造文法,只涉及‘>‘,‘<‘,‘==‘,‘!=‘和逻辑运算符‘&&‘和‘||‘。我们知道所有比较运算符都具有相同的优先级,逻辑运算符中‘&&‘优先级要比‘||‘高。所以,与四则运算的文法类似,先构建低优先级的复合表达式,最后是最高优先级的原子表达式。所以首先是描述||的规则,然后是&&,最后是原子表达式,根据上面阐述,比较运算的文法可以构造为:

compexpr : compexpr ‘||‘ andexpr
         | andexpr
andexpr : andexpr ‘&&‘ factor
        | factor
factor : ID ‘>‘ NUMBER
       | ID ‘<‘ NUMBER
       | ID ‘==‘ NUMBER
       | ID ‘!=‘ NUMBER
       | ‘(‘ compexpr ‘)‘

3.总结

     根据四则运算和比较运算的文法,我们可以总结具有优先级的表达式文法的构造原则是:

1. 从低优先级到高优先级的顺序构造规则。

2. 每个复合表达式都有一个只包含下一个优先级的表达式作为解析选项。

3. 括号具有高优先级,被括号括起的符合表达式作为原子表达式。

时间: 2024-10-13 22:20:23

[引]构造文法时表达式中算符优先级的问题的相关文章

第八章 表达式和运算符

表达式和运算符 表达式字面量 整数字面量实数字面量字符字面量字符串字面量 求值顺序 优先级结合性 简单算术运算符求余运算符关系比较运算符和相等比较运算符递增运算符和递减运算符条件逻辑运算符逻辑运算符移位运算符赋值运算符 表达式和运算符 表达式 本章将定义表达式,并描述C#提供的运算符. 运算符是一个符号,它表示返回单个结果的操作.操作数(operand)指作为运算符输入的数据元素.一个运算符会: 将操作数作为输入 执行某个操作 基于该操作返回一个值 表达式是运算符和操作数的字符串.可以作为操作数

VC项目中,构造 CString 时,提示 explicit constructors (C2440) 的解决方法

其实还是 ANSI 和 UNICODE 编码的问题. 可以使用宏 _T() 包裹字符串,使得 ANSI 和 UNICODE 兼容.如 CString strJustAnother (_T ("This is a TCHAR string a.k.a. LPCTSTR")); 或者,给那些不想改代码人的偷懒方法,屏蔽掉这个编译错误: 在 stdafx.h 文件中你一般会发现这个宏  _ATL_CSTRING_EXPLICIT_CONSTRUCTORS 的声明. #define _ATL_

python学习笔记表达式和运算符(一)

表达式和运算符 什么是表达式? 1+2*3 就是一个表达式,这里的加号和乘号叫做运算符,1.2.3叫做操作数.1+2*3 经过计算后得到的结果是7,就1+2*3 = 7.我们可以将计算结果保存在一个变量里,ret = 1-2*3 . 所以表达式就是由操作数和运算符组成的一句代码或语句,表达式可以求值,可以放在"="的右边,用来给变量赋值. 算术运算符 : + - * / //(取整除) %(取余) ** >>> 2+3 >>> 3-2 >>

JavaScript学习笔记【2】表达式和运算符、语句、对象

笔记来自<JavaScript权威指南(第六版)> 包含的内容: 表达式和运算符 语句 对象 表达式和运算符 数组直接量中的列表逗号之间的元素可以省略,这时省略的空位会填充值undefined.元素列表末尾可以留下单个逗号,这时并不会创建一个新的值为undefined元素. 属性访问表达式,.identifier的写法只适用于要访问的属性名称是合法的标识符,并且需要知道要访问的属性的名字.如果属性名称是一个保留字或者包含空格和标识符,或是一个数字(对于数组来说),则必须使用方括号的写法.当属性

JS学习第六天----表达式和运算符

表达式和运算符 1.如果不清楚运算符的优先级,最简单的办法就是使用括号来明确表明计算顺,赋值操作的优先级很低,几乎自后才被执行 2.如果"+"运算符表达式中一个是字符串,而另一个不是,则另一个会被自动转换为字符串. 如果加号运算符中一个运算数为对象,则这个对象会被转换为可以进行加法运算的数字或可以进行连接运算的字符处澳门,这一转换是通过调用该对象的valueof()或toString()方法来实现的. 3.如果"-"运算符的运算数字不是数字,那么系统会自动把它们转换

java中运算符优先级

首先不需要专门记忆,也没有必要.因为作为初学者,哪个优先级高.哪个优先级低我们很难记住.就算死记硬背记住了,时间长不用也会忘记.所以当一个表达式中有多个运算符时,如果不知道哪个优先级高哪个优先级低就查一下优先级表,附录E有一个运算符优先级表.此外用的时间长了自然而然就记住了,这样记才会记得深刻. 而且事实上在编程的时候也不需要考虑优先级的问题.因为如果不知道优先级高低的话,加一个括号就可以了,因为括号( )的优先级是最高的.比如前面的程序中: k = (j>i) && (8==i);

#、%和$符号在OGNL表达式中的作用

#.%和$符号在OGNL表达式中经常出现,而这三种符号也是开发者不容易掌握和理解的部分.在这里笔者简单介绍它们的相应用途. 1.#符号的用途一般有三种.   1)访问非根对象属性,例如示例中的#session.msg表达式,由于Struts 2中值栈被视为根对象,所以访问其他非根对象时,需要加#前缀.实际上,#相当于ActionContext. getContext():#session.msg表达式相当于ActionContext.getContext().getSession(). getA

&quot;||&quot;与&quot;or&quot;在表达式中的区别

示例1代码:$a = false || true;var_dump($a);输出结果:true说明:"||"或者的意思,优先级要高于"="等号,所以会先计算false||true这个表达式,表达式的结果为true,然后再将true这个结果赋值给变量$a,然后var_dump($a)打印出的结果为true 示例2代码:$b = false or true;var_dump($b);输出结果:false;说明:"or"或者的意思,在此表达式中优先级低

Java的表达式和运算符

一.算术运算符 运算符 + - * / % 说明 加 减 乘 除 取模(余数) 例子 1+2 5-3 20*5 6/4 30%9 结果 3 2 100 1 3 int x = 10; int y = 6; int result=x/y; System.out.println(result); 其结果是1,不会带有小数部分,也就是整数运算后的到的结果也是整数,不会自动变成浮点数. 上面所具的例子都是表示二元运算符,也就是说有两个运算参数,其中“+”和“-”两个符也可以表示一元运算符,分别表示正数和