Python版C语言词法分析器

#!/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()
时间: 2024-10-16 12:43:46

Python版C语言词法分析器的相关文章

经典C语言程序设计100例 -- C 和 Python 版 (06 - 10)

[06]格式化输出 题目:用*号输出字母C的图案. 思路:可先用'*'号在纸上写出字母C,再分行输出.如果输出图形较大,且有规律可循,可考虑使用循环. C 语言代码 int main() { const char *p = " **** \n" " ** ** \n" "** \n" "** \n" "** \n" " ** ** \n" " **** \n"; pr

编码的秘密(python版)

编码(python版) 最近在学习python的过程中,被不同的编码搞得有点晕,于是看了前人的留下的文档,加上自己的理解,准备写下来,分享给正在为编码苦苦了挣扎的你. 编码的概念 编码就是将信息从一种格式转换成另一种格式,计算机只认识二进制,简单的理解,将我们眼睛看到的文字转换为计算机能够识别的二进制格式视为编码,而二进制以某种编码格式转换为我们能看的文字的过程可以看成是解码.既然计算机只能认识二进制0,1,那么我们用的字母.数字和文字等是怎样和他们对应的呢?那就请继续看吧! python中查看

【Python】《大话设计模式》Python版代码实现

<大话设计模式>Python版代码实现 上一周把<大话设计模式>看完了,对面向对象技术有了新的理解,对于一个在C下写代码比较多.偶尔会用到一些脚本语言写脚本的人来说,很是开阔眼界.<大话设计模式>的代码使用C#写成的,而在本人接触到的面向对象语言中,只对C++和Python还算了解,为了加深对各个模式的理解,我在网上下载了一个C++版的源代码,并根据自己的理解边读这本书边动手实践C++源代码,同时将其改写成了Python代码,算是一箭三雕吧. 由于这些代码的目的是展示各

Python重写C语言程序100例--Part11

''' [程序91] 题目:时间函数举例1 1.程序分析: 2.程序源代码: ''' if __name__ == '__main__': import time print time.ctime(time.time()) print time.asctime(time.localtime(time.time())) print time.asctime(time.gmtime(time.time())) ''' [程序92] 题目:时间函数举例2 1.程序分析: 2.程序源代码: ''' if

《大话设计模式》Python版代码实现

上一周把<大话设计模式>看完了,对面向对象技术有了新的理解,对于一个在C下写代码比较多.偶尔会用到一些脚本语言写脚本的人来说,很是开阔眼界.<大话设计模式>的代码使用C#写成的,而在本人接触到的面向对象语言中,只对C++和Python还算了解,为了加深对各个模式的理解,我在网上下载了一个C++版的源代码,并根据自己的理解边读这本书边动手实践C++源代码,同时将其改写成了Python代码,算是一箭三雕吧. 由于这些代码的目的是展示各个设计模式而非完成一个具体的复杂任务,基于C++版本

python调用C语言接口

python调用C语言接口 注:本文所有示例介绍基于linux平台 *** 在底层开发中,一般是使用C或者C++,但是有时候为了开发效率或者在写测试脚本的时候,会经常使用到python,所以这就涉及到一个问题,用C/C++写的底层库,怎么样直接被python来调用? python作为一门胶水语言,当然有办法来处理这个问题,python提供的方案就是ctypes库. ctypes ctypes是python的外部函数库,它提供了C语言的兼容类型,而且可以直接调用用C语言封装的动态库. 如果各位有较

移动端自动化测试Appium 从入门到项目实战Python版

移动端自动化测试Appium 从入门到项目实战Python版 说到APP自动化测试,Appium可是说是非常流行了, 不仅支持多语言.多平台的优势,同时支持Andriod.iOS.H5的自动化测试:本课程会从初级的Appium框架讲起,涉及业界常见的po模型.关键字模型.服务自动化.持续集成等实战讲解,让你快速上手移动端自动化测试工作 appium做app自动化测试,环境搭建是比较麻烦的.也是很多初学者在学习app自动化之时,花很多时间都难跨越的坎. 但没有成功的环境,就没有办法继续后续的使用.

用蒙特卡洛方法计算派-python和R语言

用蒙特卡洛方法算pi-基于python和R语言 最近follow了MOOC上一门python课,开始学Python.同时,买来了概率论与数理统计,准备自学一下统计.(因为被鄙视过不是统计专业却想搞数据分析) 有趣的是书里面有一块讲蒲丰投针计算Pi,这是一种随机模拟法,也就是蒙特卡洛法.蒲丰投针之于我太难,暂时没想到怎么用计算机模拟这一过程. python课中,老师也提到用随机模拟法,也就是蒙特卡洛法(MonteCarlo),用计算机模拟几千次实验,计算pi的近似值.好巧. 就拿python课中的

python之simplejson,Python版的简单、 快速、 可扩展 JSON 编码器/解码器

python之simplejson,Python版的简单. 快速. 可扩展 JSON 编码器/解码器 simplejson Python版的简单. 快速. 可扩展 JSON 编码器/解码器 编码基本的 Python 对象层次结构: import simplejson as json print json.dumps(['foo', {'bar': ('baz', None, 1.0, 2)}]) print json.dumps("\"foo\bar") print json