Python版C语言词法分析器
一个带有图形界面的C语言词法分析器,版本为Python2.7。
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
from Tkinter import *
from tkFont import *
from FileDialog import * KEYWORD_LIST = ['if', 'else', 'while', 'break', 'continue', 'for', 'double', 'int', 'float', 'long', 'short', 'bool',
'switch', 'case', 'return', 'void'] SEPARATOR_LIST = ['{', '}', '[', ']', '(', ')', '~', ',', ';', '.', '?', ':', ' '] OPERATOR_LIST = ['+', '++', '-', '--', '+=', '-=', '*', '*=', '%', '%=', '->', '|', '||', '|=',
'/', '/=', '>', '<', '>=', '<=', '=', '==', '!=', '!', '&'] CATEGORY_DICT = {
# KEYWORD
"far": 257,
"near": 258,
"pascal": 259,
"register": 260,
"asm": 261,
"cdecl": 262,
"huge": 263,
"auto": 264,
"double": 265,
"int": 266,
"struct": 267,
"break": 268,
"else": 269,
"long": 270,
"switch": 271,
"case": 272,
"enum": 273,
"register": 274,
"typedef": 275,
"char": 276,
"extern": 277,
"return": 278,
"union": 279,
"const": 280,
"float": 281,
"short": 282,
"unsigned": 283,
"continue": 284,
"for": 285,
"signed": 286,
"void": 287,
"default": 288,
"goto": 289,
"sizeof": 290,
"volatile": 291,
"do": 292,
"if": 293,
"while": 294,
"static": 295,
"interrupt": 296,
"sizeof": 297,
"NULL": 298,
# SEPARATOR
"{": 299,
"}": 300,
"[": 301,
"]": 302,
"(": 303,
")": 304,
"~": 305,
",": 306,
";": 307,
".": 308,
"#": 309,
"?": 310,
":": 311,
# OPERATOR
"<<": 312,
">>": 313,
"<": 314,
"<=": 315,
">": 316,
">=": 317,
"=": 318,
"==": 319,
"|": 320,
"||": 321,
"|=": 322,
"^": 323,
"^=": 324,
"&": 325,
"&&": 326,
"&=": 327,
"%": 328,
"%=": 329,
"+": 330,
"++": 331,
"+=": 332,
"-": 333,
"--": 334,
"-=": 335,
"->": 336,
"/": 337,
"/=": 338,
"*": 339,
"*=": 340,
"!": 341,
"!=": 342,
"sizeof": 343,
"<<=": 344,
">>=": 345,
"inum": 346,
"int16": 347,
"int8": 348,
"char": 350,
"string": 351,
"bool": 352,
"fnum": 353,
"IDN": 354
} current_row = -1
current_line = 0
out_line = 1 def getchar(input_str):
global current_row
global current_line
current_row += 1 if current_row == len(input_str[current_line]):
current_line += 1
current_row = 0 if current_line == len(input_str) - 1:
return 'SCANEOF' return input_str[current_line][current_row] def ungetchar(input_str):
global current_row
global current_line
current_row = current_row - 1
if current_row < 0:
current_line = current_line - 1
current_row = len(input_str[current_row]) - 1
return input_str[current_line][current_row] def error(msg, line=None, row=None):
global out_line
if line is None:
line = current_line + 1
if row is None:
row = current_row + 1
analysis.insert(str(out_line) + '.0', str(line) + ':' + str(row) + 'Error: ' + msg)
analysis.insert(str(out_line) + '.end', "\n")
out_line = out_line + 1 def scanner(input_str):
global current_line
global current_row
current_char = getchar(input_str)
if current_char == 'SCANEOF':
return ('SCANEOF', '', '')
if current_char.strip() == '':
return
if current_char.isdigit():
int_value = 0
while current_char.isdigit():
int_value = int_value * 10 + int(current_char)
current_char = getchar(input_str)
if current_char not in OPERATOR_LIST and current_char not in SEPARATOR_LIST and current_char != 'e':
line = current_line + 1
row = current_row + 1
# ungetchar(input_str)
error('illigal identifier', line, row)
# return ('SCANEOF', '', '')
return ('', '', '')
if current_char != '.' and current_char != 'e':
ungetchar(input_str)
return ('INUM', int_value, CATEGORY_DICT['inum'])
if current_char == 'e':
power_value = str(int_value) + 'e'
current_char = getchar(input_str)
if current_char == '+' or current_char == '-':
power_value += current_char
current_char = getchar(input_str)
while current_char.isdigit():
power_value += current_char
current_char = getchar(input_str)
if current_char not in OPERATOR_LIST and current_char not in SEPARATOR_LIST:
line = current_line + 1
row = current_row + 1
# ungetchar(input_str)
error('illigal const int value in power', line, row)
# return ('SCANEOF', '', '')
return ('', '', '')
ungetchar(input_str)
return ('INUM', power_value, CATEGORY_DICT['inum'])
if current_char == '.':
float_value = str(int_value) + '.'
current_char = getchar(input_str)
while current_char.isdigit():
float_value += current_char
current_char = getchar(input_str)
if current_char not in OPERATOR_LIST and current_char not in SEPARATOR_LIST or current_char == '.':
line = current_line + 1
row = current_row + 1
# ungetchar(input_str)
error('illigal const float value', line, row)
# return ('SCANEOF', '', '')
return ('', '', '')
ungetchar(input_str)
return ('FNUM', float_value, CATEGORY_DICT['fnum'])
if current_char.isalpha() or current_char == '_':
string = ''
while current_char.isalpha() or current_char.isdigit() or current_char == '_' and current_char != ' ':
string += current_char
current_char = getchar(input_str)
if current_char == 'SCANEOF':
break
ungetchar(input_str)
if string in KEYWORD_LIST:
return (string, '', CATEGORY_DICT[string])
else:
return ('IDN', string, CATEGORY_DICT['IDN']) if current_char == '\"':
str_literal = ''
line = current_line + 1
row = current_row + 1 current_char = getchar(input_str)
while current_char != '\"':
str_literal += current_char
current_char = getchar()
if current_char == 'SCANEOF':
error('missing terminating \"', line, row)
current_line = line
current_row = row
return ('SCANEOF', '', '')
return ('STRING_LITERAL', str_literal, CATEGORY_DICT['string']) if current_char == '/':
next_char = getchar(input_str)
line = int(current_line) + 1
row = int(current_row) + 1
if next_char == '*':
comment = ''
next_char = getchar(input_str)
while True:
if next_char == 'SCANEOF':
error('unteminated /* comment', line, row)
return ('SCANEOF', '', '')
if next_char == '*':
end_char = getchar(input_str)
if end_char == '/':
return None
if end_char == 'SCANEOF':
error('unteminated /* comment', line, row)
return ('SCANEOF', '', '')
comment += next_char
next_char = getchar(input_str)
else:
ungetchar(input_str)
op = current_char
current_char = getchar(input_str)
if current_char in OPERATOR_LIST:
op += current_char
else:
ungetchar(input_str)
return ('OP', op, CATEGORY_DICT[op]) if current_char in SEPARATOR_LIST:
return ('SEP', current_char, CATEGORY_DICT[current_char]) if current_char in OPERATOR_LIST:
op = current_char
current_char = getchar(input_str)
if current_char in OPERATOR_LIST:
op += current_char
else:
ungetchar(input_str)
return ('OP', op, CATEGORY_DICT[op])
else:
error('unknown character: ' + current_char) def fileloader():
global root
code.delete(1.0, END)
fd = LoadFileDialog(root)
filename = fd.go()
fin = open(filename, "r")
input_file = fin.read()
input_lines = input_file[0].split("\n")
code.insert(1.0, input_file)
fin.close() def lexer_analysis(input_str):
global current_row
global current_line
global out_line
current_row = -1
current_line = 0
analysis_result = [] while True:
r = scanner(input_str)
if r is not None:
if r[0] == 'SCANEOF':
break
analysis_result.append(str(r[0]) + "\t\t" + str(r[1]) + "\t\t" + str(r[2]))
return analysis_result def lexer():
input_str = []
analysis.delete(1.0, END)
input_raw = code.get(1.0, END)
input_str = input_raw.split("\n")
lexer_analysis(input_str) out_line = 1
result = lexer_analysis(input_str)
for each in result:
analysis.insert(str(out_line) + '.end', each)
analysis.insert(str(out_line) + '.end', "\n")
out_line = out_line + 1 def pre_interface(): global root
global code
global analysis
root = Tk()
code = Text(root, width=60, height=20, font=15)
analysis = Text(root, width=60, height=20, font=15) t = StringVar()
t.set('Patrick的词法分析器')
label = Label(root, textvariable=t, font=15)
Analysis = Button(root, text='词法分析', command=lexer, font=15)
load = Button(root, text=' 载入代码 ', command=fileloader, font=15)
root.title("LEXER")
label.pack(side=TOP)
Analysis.pack(side=BOTTOM)
load.pack(side=BOTTOM)
code.pack(side=LEFT)
analysis.pack(side=RIGHT)
root.mainloop() def main():
pre_interface() # lexer() if __name__ == '__main__':
main()
Python版C语言词法分析器的更多相关文章
- 编码的秘密(python版)
编码(python版) 最近在学习python的过程中,被不同的编码搞得有点晕,于是看了前人的留下的文档,加上自己的理解,准备写下来,分享给正在为编码苦苦了挣扎的你. 编码的概念 编码就是将信息从一种 ...
- 豆瓣top250(go版以及python版)
最近学习go,就找了一个例子练习[go语言爬虫]go语言爬取豆瓣电影top250,思路大概就是获取网页,然后根据页面元素,用正则表达式匹配电影名称.评分.评论人数.原文有个地方需要修改下patte ...
- 【Python】《大话设计模式》Python版代码实现
<大话设计模式>Python版代码实现 上一周把<大话设计模式>看完了,对面向对象技术有了新的理解,对于一个在C下写代码比较多.偶尔会用到一些脚本语言写脚本的人来说,很是开阔眼 ...
- python之 python 起源、语言特点
一. 1.1 什么是 PythonPython 是一门优雅而健壮的编程语言,它继承了传统编译语言的强大性和通用性,同时也借鉴了简单脚本和解释语言的易用性.它可以帮你完成工作,而且一段时间以后,你还能 ...
- ROS Learning-011 beginner_Tutorials (编程) 编写 ROS 话题版的 Hello World 程序(Python版)
ROS Indigo beginner_Tutorials-10 编写 ROS 话题版的 Hello World 程序(Python版) 我使用的虚拟机软件:VMware Workstation 11 ...
- 《大话设计模式》Python版代码实现
上一周把<大话设计模式>看完了,对面向对象技术有了新的理解,对于一个在C下写代码比较多.偶尔会用到一些脚本语言写脚本的人来说,很是开阔眼界.<大话设计模式>的代码使用C#写成的 ...
- 自己动手实现智能家居之树莓派GPIO简介(Python版)
[前言] 一个热爱技术的人一定向往有一个科技感十足的环境吧,那何不亲自实践一下属于技术人的座右铭:“技术改变世界”. 就让我们一步步动手搭建一个属于自己的“智能家居平台”吧(不要对这个名词抬杠啦,技术 ...
- 移动端自动化测试Appium 从入门到项目实战Python版☝☝☝
移动端自动化测试Appium 从入门到项目实战Python版 (一个人学习或许会很枯燥,但是寻找更多志同道合的朋友一起,学习将会变得更加有意义✌✌) 说到APP自动化测试,Appium可是说是非常流 ...
- python调用C语言接口
python调用C语言接口 注:本文所有示例介绍基于linux平台 在底层开发中,一般是使用C或者C++,但是有时候为了开发效率或者在写测试脚本的时候,会经常使用到python,所以这就涉及到一个问题 ...
随机推荐
- C#遍历文件名
遍历文件名程序 //////////////////第一种方法///////////// static ArrayList GetAllFiles(string path) { ArrayList r ...
- Java集合之ArrayList源码分析
1.简介 List在数据结构中表现为是线性表的方式,其元素以线性方式存储,集合中允许存放重复的对象,List接口主要的实现类有ArrayList和LinkedList.Java中分别提供了这两种结构的 ...
- 【Android开发日记】妙用 RelativeLayout 实现3
段布局
在设计过程中,我们经常会遇到这样的需求: 把一条线3控制,左对齐左控制,右侧控制右对齐,中间控制,以填补剩余空间. 或者一列内放3个控件,上面的与顶部对齐,以下的沉在最底部,中间控件是弹性的.充满剩余 ...
- bash元字符(上)
元字符 行动 样例 回车换行 结束一个命令 空格 切割命令行中的元素 ls /etc Tab 命令自己主动补全 # 開始一行凝视 #This is a comment line " 引用多个 ...
- hexo github
win 安装nodejs,用nodejs cmd执行 npm install -g hexo hexo init blog cd blog npm install 或者新建文件夹,进去init再npm ...
- Oracle wrap 和 unwrap( 加密与解密) 说明
一. Wrap 说明 官网的说明如下: A PL/SQL Source Text Wrapping http://download.oracle.com/docs/cd/E11882_01/appde ...
- 简话ASP.NET Web API
简话ASP.NET Web API 在vs2012中,我们很容易在根据选择的ASP.NET MVC Web应用程序来新建一个Web API应用,聪明的你一定想见得到,Web API和MVC有着某种联系 ...
- openGL的使用步骤
使用openGL步骤:1.创建GLSurfaceView对象2.创建GLSurfaceView.renderer实现类.3.设置activity的contentView,以及设置view的render ...
- SpringMVC 异常处理
SpringMVC学习系列(10) 之 异常处理 在项目中如何处理出现的异常,在每个可能出现异常的地方都写代码捕捉异常?这显然是不合理的,当项目越来越大是也是不可维护的.那么如何保证我们处理异常的代码 ...
- 尝试使用Memcached
尝试使用Memcached遇到的狗血问题 乘着有时间,尝试下利用Memcached进行分布式缓存,其中遇到了不少问题及狗血的事情,开篇记录下,希望对您有帮助. 我之前的项目为:Asp.Net MV ...