如何用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清除指定目录内所有文件中script的方法
Jun 30 Python
python 获取指定文件夹下所有文件名称并写入列表的实例
Apr 23 Python
Python中跳台阶、变态跳台阶与矩形覆盖问题的解决方法
May 19 Python
对python中array.sum(axis=?)的用法介绍
Jun 28 Python
实例讲解Python中整数的最大值输出
Mar 17 Python
Python JSON格式数据的提取和保存的实现
Mar 22 Python
Django admin.py 在修改/添加表单界面显示额外字段的方法
Aug 22 Python
PyQt5事件处理之定时在控件上显示信息的代码
Mar 25 Python
Django import export实现数据库导入导出方式
Apr 03 Python
PyQt5通过信号实现MVC的示例
Feb 06 Python
教你怎么用python爬取爱奇艺热门电影
May 20 Python
使用Python脚本对GiteePages进行一键部署的使用说明
May 27 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
一周学会PHP(视频)Http下载
2006/12/12 PHP
PHP 日志缩略名的创建函数代码
2010/05/26 PHP
php程序的国际化实现方法(利用gettext)
2011/08/14 PHP
探讨:php中在foreach中使用foreach ($arr as &amp;$value) 这种类型的解释
2013/06/24 PHP
使用ThinkPHP+Uploadify实现图片上传功能
2014/06/26 PHP
PHP代码实现爬虫记录――超管用
2015/07/31 PHP
Laravel中使用FormRequest进行表单验证方法及问题汇总
2016/06/19 PHP
PHP实现的同步推荐操作API接口案例分析
2016/11/30 PHP
分享5个非常有用的Laravel Blade指令
2018/05/30 PHP
Mootools 1.2教程 同时进行多个形变动画
2009/09/15 Javascript
JavaScript中的this实例分析
2011/04/28 Javascript
基于jquery实现拆分姓名的方法(纯JS版)
2013/05/08 Javascript
jquery easyui 结合jsp简单展现table数据示例
2014/04/18 Javascript
bootstrap输入框组代码分享
2016/06/07 Javascript
JS实现鼠标框选效果完整实例
2016/06/20 Javascript
详解vuejs几种不同组件(页面)间传值的方式
2017/06/01 Javascript
微信小程序实现下载进度条的方法
2017/12/08 Javascript
vue单页面打包文件大?首次加载慢?nginx带你飞,从7.5M到1.3M蜕变过程(推荐)
2018/01/16 Javascript
对vux点击事件的优化详解
2018/08/28 Javascript
深入理解Python中字典的键的使用
2015/08/19 Python
Python正则表达式如何进行字符串替换实例
2016/12/28 Python
通过Pandas读取大文件的实例
2018/06/07 Python
python实现布隆过滤器及原理解析
2019/12/08 Python
python 利用已有Ner模型进行数据清洗合并代码
2019/12/24 Python
使用TensorFlow对图像进行随机旋转的实现示例
2020/01/20 Python
python单元测试框架pytest的使用示例
2020/10/07 Python
CSS3+Sprite实现僵尸行走动画特效源码
2016/01/27 HTML / CSS
Alba Moda瑞士网上商店:独家意大利时尚女装销售
2016/11/28 全球购物
荷兰网上药店:Drogisterij.net
2019/09/03 全球购物
家长对学生的评语
2014/04/18 职场文书
文秘自荐信
2014/06/28 职场文书
房屋转让协议书
2014/10/18 职场文书
中标通知书范本
2015/04/17 职场文书
《作风建设永远在路上》心得体会
2016/01/21 职场文书
python爬虫请求库httpx和parsel解析库的使用测评
2021/05/10 Python
Java 将PPT幻灯片转为HTML文件的实现思路
2021/06/11 Java/Android