用LL(1)递归下降语法器构造一个计算器

LL(1)

何为LL(1)?通俗来说就是向前看一个词法单元的自顶向下解析器。两个L都代表left-to-right,第一个L表示解析器按“从左到右”的顺序解析输入内容;第二个L表示下降解析时也是按“从左到右”的顺序遍历子节点。而(1)表示它使用一个向前看 词法单元。

我们从一个简单的计算器来看看递归下降的语法器如何构造。

对于 2 + 3 * 5 的抽象语法树如下:

我们可以使用如下文法表示计算表达式:

# expr ::= expr addop term | term
# term ::= term mulop factor | factor
# factor ::= number | ( expr )
# addop ::= + | -
# mulop ::= * | /

 1 import tokenize, StringIO
 2 
 3 tokens = None
 4 cur_tok = None
 5 
 6 def scan(text):
 7     g = tokenize.generate_tokens(
 8         StringIO.StringIO(text).readline)
 9     return ((v[0], v[1]) for v in g)
10     
11 def get_token():
12     global tokens, cur_tok
13     cur_tok = tokens.next()
14     #print cur_tok
15     return cur_tok
16     
17 def match(type, val = ''):
18     global tokens, cur_tok
19     t, v = cur_tok
20     if t == type or t == tokenize.OP and v == val:
21         get_token()
22     else:
23         raise 
24 
25 def expr():
26     global cur_tok
27     tmp = term()
28     t, v = cur_tok
29     while v == '+' or v == '-':
30         match(tokenize.OP)
31         rhs = term()
32         e = str(tmp) + str(v) + str(rhs)
33         tmp = eval(e)
34         print e, '=', tmp
35         t, v = cur_tok
36     return tmp 
37 
38 def term():
39     global cur_tok
40     tmp = factor()
41     t, v = cur_tok
42     while v == '*' or v == '/':
43         match(tokenize.OP)
44         rhs = factor()
45         e = str(tmp) + str(v) + str(rhs)
46         tmp = eval(e)
47         print e, '=', tmp
48         t, v = cur_tok
49     return tmp
50 
51 def factor():
52     global cur_tok
53     t, v = cur_tok
54     if t == tokenize.NUMBER:
55         match(tokenize.NUMBER)
56         return int(v)
57     elif v == '(':
58         match(tokenize.OP, '(')
59         tmp = expr()
60         match(tokenize.OP, ')')
61         return tmp
62     else:
63         raise
64 
65 if __name__ == '__main__':
66     text = '12 + 2 * ( 5 + 6 )'
67     tokens = scan(text)
68     get_token()
69     res = expr()
70     print text, '=', res

对于12 + 2 * ( 5 + 6 ),运行结果如下:

转载于:https://www.cnblogs.com/huazi/archive/2012/12/15/2818881.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
递归下降分析法 一、实验目的: 根据某一文法编制调试递归下降分析程序,以便对任意输入的符号串进行分析。本次实验的目的主要是加深对递归下降分析法的理解。 二、实验说明 1、递归下降分析法的功能 词法分析的功能是利用函数之间的递归调用模拟语法树自上而下的构造过程。 2、递归下降分析法的前提 改造文法:消除二义性、消除左递归、提取左因子,判断是否为LL(1)文法, 3、递归下降分析法实验设计思想及算法 为G的每个非终结符号U构造一个递归过程,不妨命名为U。 U的产生式的右边指出这个过程的代码结构: (1)若是终结符号,则和向前看符号对照, 若匹配则向前进一个符号;否则出错。 (2)若是非终结符号,则调用与此非终结符对应的过程。当A的右部有多个产生式时,可用选择结构实现。 三、实验要求 (一)准备: 1.阅读课本有关章节, 2.考虑好设计方案; 3.设计出模块结构、测试数据,初步编制好程序。 (二)上课上机: 将源代码拷贝到机上调试,发现错误,再修改完善。第二次上机调试通过。 (三)程序要求: 程序输入/输出示例: 对下列文法,用递归下降分析法对任意输入的符号串进行分析: (1)E->eBaA (2)A->a|bAcB (3)B->dEd|aC (4)C->e|dc 输出的格式如下: (1)递归下降分析程序,编制人:姓名,学号,班级 (2)输入一以#结束的符号串:在此位置输入符号串例如:eadeaa# (3)输出结果:eadeaa#为合法符号串 注意: 1.如果遇到错误的表达式,应输出错误提示信息(该信息越详细越好); 2.对学有余力的同学,可以详细的输出推导的过程,即详细列出每一步使用的产生式。 (四)程序思路 0.定义部分:定义常量、变量、数据结构。 1.初始化:从文件将输入符号串输入到字符缓冲区中。 2.利用递归下降分析法分析,对每个非终结符编写函数,在主函数中调用文法开始符号的函数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值