python编程(ply库)

栏目: Python · 发布时间: 8年前

内容简介: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这个 工具 好好了解一下。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Pro JavaScript Techniques

Pro JavaScript Techniques

John Resig / Apress / 2006-12-13 / USD 44.99

Pro JavaScript Techniques is the ultimate JavaScript book for the modern web developer. It provides everything you need to know about modern JavaScript, and shows what JavaScript can do for your web s......一起来看看 《Pro JavaScript Techniques》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具