内容简介:python编程(ply库)
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】
长久以来,我一直对编译器都比较感兴趣。网上,大家推荐的龙书、《自制编译器》等等虽然也看过,但是我觉得都没有办法满足自己编写工业软件的要求。后来有一次看lua,发现 lua 早期也是使用lex&yacc完成字符解析的,一下子找到了方法。最近因为使用 python 的关系,想看看python有没有类似的库,结果就找到了ply库。
1、安装ply库
建议大家到 官网 下载,直接利用源代码安装
sudo python setup.py install
偷懒一点的朋友,也可以直接用apt安装,
sudo apt-get install python-ply
2、ply资料
关于ply的资料,最权威的还是 官方文档 。
3、词法分析和语法分析
和lex、yacc工具不同,ply本身的规则文件也是编写成python形式的。而lex和yacc都是将规则文件转换成c文件,然后一起编译。
4、示例代码
这份示例代码也是根据官网的代码做了一点修改。其中calclex.py完成词法分析,calc.py完成语法分析。
calclex.py文件如下,
##!/bin/python # ------------------------------------------------------------ # calclex.py # # tokenizer for a simple expression evaluator for # numbers and +,-,*,/ # ------------------------------------------------------------ import ply.lex as lex # List of token names. This is always required tokens = ( 'NUMBER', 'PLUS', 'MINUS', 'TIMES', 'DIVIDE', 'LPAREN', 'RPAREN', ) # Regular expression rules for simple tokens t_PLUS = r'\+' t_MINUS = r'-' t_TIMES = r'\*' t_DIVIDE = r'/' t_LPAREN = r'\(' t_RPAREN = r'\)' # A regular expression rule with some action code def t_NUMBER(t): r'\d+' t.value = int(t.value) return t # Define a rule so we can track line numbers def t_newline(t): r'\n+' t.lexer.lineno += len(t.value) # A string containing ignored characters (spaces and tabs) t_ignore = ' \t' # Error handling rule def t_error(t): print("Illegal character '%s'" % t.value[0]) t.lexer.skip(1) # Build the lexer lexer = lex.lex()
calc.py文件如下,
# Yacc example import ply.yacc as yacc # Get the token map from the lexer. This is required. from calclex import tokens def p_add(p): 'expression : expression PLUS term' p[0] = p[1] + p[3] def p_sub(p): 'expression : expression MINUS term' p[0] = p[1] - p[3] def p_term(p): 'expression : term' p[0] = p[1] def p_term_factor(p): 'term : term TIMES factor' p[0] = p[1] * p[3] def p_term_divide(p): 'term : term DIVIDE factor' p[0] = p[1] / p[3] def p_factor(p): 'term : factor' p[0] = p[1] def p_factor_num(p): 'factor : NUMBER' p[0] = p[1] def p_fact_param(p): 'factor : LPAREN expression RPAREN' p[0] = p[2] # Error rule for syntax errors def p_error(p): print("Syntax error in input!") # Build the parser parser = yacc.yacc() while True: try: s = raw_input('calc > ') except EOFError: break if not s: continue if s == 'q' or s =='Q': break result = parser.parse(s) print(result)
5、添加Makefile
因为编译的时候会生成很多中间文件,所以建议大家可以编一个Makefile,完成自动化清理和执行的工作。
.PHONY: all clean all: run run:process clean process: python calc.py clean: @rm -rf parser.out *.pyc parsetab.py
6、后续
关于lex&yacc其实有两种用法,一种是生成ast,也就是抽象语法树,这样可以进一步进行语义分析、生成中间语言、优化、生成汇编代码等等。另外一种就是直接生成执行语言,这也是大多数脚本语言的做法,比如lua。脚本语言特别适合无编译运行,此外它的动态加载、垃圾回收、和c自由交互等系列功能也很实用。希望大家可以借ply这个 工具 好好了解一下。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 编程范式 —— 函数式编程入门
- 【go网络编程】-HTTP编程
- 【go网络编程】-Socket编程
- c++并发编程—分布式编程
- Scala面向对象编程之Trait高级编程技术实践-JVM生态编程语言实战
- 函数式编程之数组的函数式编程
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Node.js实战
[美] Mike Cantelon、[美] TJ Holowaychuk、[美] Nathan Rajlich / 吴海星 / 人民邮电出版社 / 2014-5 / 69.00元
服务器端JavaScript?没错。Node.js是一个JavaScript服务器,支持可伸缩的高性能Web应用。借助异步I/O,这个服务器可以同时做很多事情,能满足聊天、游戏和实时统计等应用的需求。并且既然是JavaScript,那你就可以全栈使用一种语言。 本书向读者展示了如何构建产品级应用,对关键概念的介绍清晰明了,贴近实际的例子,涵盖从安装到部署的各个环节,是一部讲解与实践并重的优秀......一起来看看 《Node.js实战》 这本书的介绍吧!