如何用python写一个简单的词法分析器


Posted in Python onDecember 18, 2018

编译原理老师要求写一个java的词法分析器,想了想决定用python写一个。

目标

能识别出变量,数字,运算符,界符和关键字,用excel表打印出来。

有了目标,想想要怎么实现词法分析器。

1.先进行预处理,把注释,多余的空格,空行去掉。

2.一行一行扫描,行里逐字扫描,把界符和运算符当做分割符,遇到就先停下开始判断。

  • 若是以 英文字母、$、下划线开头,则可能是变量和关键字,在判断是关键字还是变量。
  • 若是数字开头,则判断下一位是不是也是数字,直到遇到非数字停止,在把数字取出来。
  • 再来判断分割符是什么类型,是界符还是运算符。

在给不同词添加上识别码

在用excel表打印出来。

代码实现

 1. 用列表创建一个关键字表,java关键字有50个。

#保留字
key_word = ['abstract','assert','boolean','break','byte',
      'case','catch','char','class','const',
      'continue','default','do','double','else',
      'enum','extends','final','finally','float',
      'for','goto','if','implements','import',
      'instanceof','int','interface','long','native',
      'new','package','private','protected','public',
      'return','short','static','strictfp','super',
      'switch','synchronized','this','throw','throws',
      'transient','try','void','volatile','while']

2.用列表创建一个运算符表。

#运算符
operator = ['+','-','*','/','%','++','--','+=','-=','+=','/=',#算术运算符
      '==','!=','>','<','>=','<=',#关系运算符
      '&','|','^','~','<<','>>','>>>',#位运算符
      '&&','||','!',#逻辑运算符
      '=','+=','-=','*=','/=','%=','<<=','>>=','&=','^=','|=',#赋值运算符
      '?:']#条件运算符

3. 用列表创建一个界符表。

#界符
delimiters = ['{','}','[',']','(',')','.',',',':',';']

4.预处理

用正则表达式把注释去掉,在把多余的空行去掉

#预处理
def filterResource(file,new_file):
  f2 = open(new_file,'w+')
  txt = ''.join(open(file,'r').readlines())
  deal_txt = re.sub(r'\/\*[\s\S]*\*\/|\/\/.*','',txt) 
  for line in deal_txt.split('\n'):
      line = line.strip()
      line = line.replace('\\t','')
      line = line.replace('\\n','')
      if not line:
        continue
      else:
        f2.write(line+'\n')
  f2.close()
  return sys.path[0]+'\\'+ new_file

5.逐行扫描

按照刚刚的思路进行判断,把每一行的单词,添加到word_line列表中,最后在把每一行添加到token列表中。

def Scan(file):
  lines = open(file,'r').readlines()
  for line in lines:
    word = ''
    word_line = []
    i = 0
    while i <len(line):
      word +=line[i]
      if line[i]==' ' or line[i] in delimiters or line[i] in operator:
        if word[0].isalpha() or word[0]=='$' or word[0]=='_':
          word = word[:-1]
          if searchReserve(word):
            # 保留字
            word_line.append({word[:-1]:key_word.index(word)})
          else:
            # 标识符
            identifier.append({word:-2})
            word_line.append({word:-2})
        # 常数
        elif word[:-1].isdigit():
          word_line.append({word:-1})
        #else:
          #error_word.append(word)
        # 字符是界符
        if line[i] in delimiters:
          word_line.append({line[i]:len(key_word)+delimiters.index(line[i])})
        # 字符是运算符
        elif line[i] in operator:
          s = line[i] +line[i+1]
          if s in operator:
            word_line.append({s:len(key_word)+len(delimiters)+operator.index(s)})
            i +=1
          else:
            word_line.append({line[i]:len(key_word)+len(delimiters)+operator.index(line[i])})
        word = ''
      i+=1
    token.append(word_line)

6.根据单词返回是什么类型

按照保留字--界符--运算符--常数的顺序来当识别码。常数识别码是-1,标识符识别码是-2

def check(number):
  hanzi = ''
  q = len(key_word)
  w = len(delimiters)
  e = len(operator)
  if 0<number<=q:
    hanzi = '保留字'
  elif q<number <= q+w:
    hanzi = '界符'
  elif q+w<number <=q+w+e:
    hanzi = '运算符'
  elif number == -1:
    hanzi ='常数'
  elif number == -2:
    hanzi ='标识符'
  return hanzi

7. 用thinker写一个简单的界面

导入

from tkinter import * 
from tkinter.filedialog import askdirectory,askopenfilename
root = Tk()
  root.title('词法分析')
  root.resizable(0, 0)
  path = StringVar() 
  Label(root,text = "目标路径:").grid(row = 0, column = 0) 
  Entry(root, textvariable = path).grid(row = 0, column = 1) 
  Button(root, text = "路径选择", command = openfiles).grid(row = 0, column = 2)
  Button(root,text='词法分析',command= open_excel).grid(row = 0,column = 3)
  root.mainloop()

打开文件

def openfiles():
  fname = askopenfilename(title='打开文件', filetypes=[('All Files', '*')])
  path.set(fname)

如何用python写一个简单的词法分析器

简单的界面

8.导入到excel表中

需要安装包xwings

pip install xwings

导入

import xlwings as xw

把token里的单词,按照 单词 ---- 识别码 ---类型 打印到excel表中

def open_excel():
  # 预处理
  row,col=0,0
  if path.get()!='':

    txt = java_analysis.filterResource(path.get(),new_file)
    print(txt)
    #扫描
    java_analysis.Scan(txt)
    app = xw.App(visible=True,add_book=False)
    wb =app.books.open(sys.path[0]+'\\'+'test.xlsx')
    sheet = wb.sheets.active
    sheet.clear() 
    print(java_analysis.token)
    for i in range(len(java_analysis.token)):
      sheet[row,0].value = '第'+str(i+1)+'行'
      row +=1
      for word in java_analysis.token[i]:
        for k,w in word.items():
          sheet[row,3].value = k
          sheet[row,5].value = w
          sheet[row,7].value = java_analysis.check(w)
        row +=1
    sheet.autofit()#整个sheet自动调整
    #wb.save()

最后就像这样

如何用python写一个简单的词法分析器

效果

代码很烂,不过也算是大致明白词法分析器了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python内建模块struct实例详解
Feb 02 Python
Python爬虫爬取新浪微博内容示例【基于代理IP】
Aug 03 Python
python 通过 socket 发送文件的实例代码
Aug 14 Python
python3使用pandas获取股票数据的方法
Dec 22 Python
selenium 安装与chromedriver安装的方法步骤
Jun 12 Python
Django后端接收嵌套Json数据及解析详解
Jul 17 Python
python mqtt 客户端的实现代码实例
Sep 25 Python
python计算导数并绘图的实例
Feb 29 Python
Python 为什么推荐蛇形命名法原因浅析
Jun 18 Python
Python logging模块进行封装实现原理解析
Aug 07 Python
Python实战之OpenCV实现猫脸检测
Jun 26 Python
教你用python实现12306余票查询
Jun 30 Python
详解Python requests 超时和重试的方法
Dec 18 #Python
解决新django中的path不能使用正则表达式的问题
Dec 18 #Python
python 获取url中的参数列表实例
Dec 18 #Python
python 函数内部修改外部变量的方法
Dec 18 #Python
Python实现获取汉字偏旁部首的方法示例【测试可用】
Dec 18 #Python
python监测当前联网状态并连接的实例
Dec 18 #Python
Python实现繁体中文与简体中文相互转换的方法示例
Dec 18 #Python
You might like
计数器详细设计
2006/10/09 PHP
如何提高MYSQL数据库的查询统计速度 select 索引应用
2007/04/11 PHP
在PHP中实现Javascript的escape()函数代码
2010/08/08 PHP
php数据访问之增删改查操作
2016/05/09 PHP
Zend Framework上传文件重命名的实现方法
2016/11/25 PHP
PHP实现链表的定义与反转功能示例
2018/06/09 PHP
JavaScript URL参数读取改进版
2009/01/16 Javascript
jQuery 常见学习网站与参考书
2009/11/09 Javascript
js 获取时间间隔实现代码
2014/05/12 Javascript
javascript中setInterval的用法
2015/07/19 Javascript
基于jQuery的select下拉框选择触发事件实例分析
2016/11/18 Javascript
DOM 事件的深入浅出(一)
2016/12/05 Javascript
微信小程序 input输入框控件详解及实例(多种示例)
2016/12/14 Javascript
jQuery实现可拖拽3D万花筒旋转特效
2017/01/03 Javascript
详解VUE 定义全局变量的几种实现方式
2017/06/01 Javascript
React + webpack 环境配置的方法步骤
2017/09/07 Javascript
Vue 自定义动态组件实例详解
2018/03/28 Javascript
在AngularJs中设置请求头信息(headers)的方法及不同方法的比较
2018/09/04 Javascript
小程序组件之仿微信通讯录的实现代码
2018/09/12 Javascript
详解小程序设置缓存并且不覆盖原有数据
2019/04/15 Javascript
基于JS实现计算24点算法代码实例解析
2020/07/23 Javascript
JavaScript实现点击出现子菜单效果
2021/02/08 Javascript
Python列表list操作符实例分析【标准类型操作符、切片、连接字符、列表解析、重复操作等】
2017/07/24 Python
Python使用selenium + headless chrome获取网页内容的方法示例
2019/10/16 Python
Python基于locals返回作用域字典
2020/10/17 Python
DRF使用simple JWT身份验证的实现
2021/01/14 Python
美国知名运动产品零售商:Foot Locker
2016/07/23 全球购物
入党自我评价范文
2014/02/02 职场文书
2014年道德讲堂实施方案
2014/03/05 职场文书
应聘英语教师求职信
2014/04/24 职场文书
市场开发计划书
2014/05/07 职场文书
安全生产月宣传标语
2014/10/06 职场文书
2014年护士长工作总结
2014/11/11 职场文书
电影地道战观后感
2015/06/04 职场文书
Python selenium绕过webdriver监测执行javascript
2022/04/12 Python
微信小程序实现轮播图指示器
2022/06/25 Javascript