Python中的C词法分析器

0 投票
3 回答
9922 浏览
提问于 2025-04-16 05:54

我正在用Python创建一个C语言的词法分析器,这是我开发解析器的一部分。在我的代码中,我写了一些方法来识别关键字、数字、运算符等等。编译后没有显示错误。当我执行时,可以输入一个.c文件。我的输出应该列出输入文件中的所有关键字、标识符等。但是它什么都没有显示。有没有人能帮我解决这个问题?代码已附上。

import sys
import string
delim=['\t','\n',',',';','(',')','{','}','[',']','#','<','>']
oper=['+','-','*','/','%','=','!']
key=["int","float","char","double","bool","void","extern","unsigned","goto","static","class","struct","for","if","else","return","register","long","while","do"]
predirect=["include","define"]
header=["stdio.h","conio.h","malloc.h","process.h","string.h","ctype.h"]
word_list1=""
i=0
j=0
f=0
numflag=0
token=[0]*50


def isdelim(c):
    for k in range(0,14):
        if c==delim[k]:
            return 1
        return 0

def isop(c):
    for k in range(0,7):
        if c==oper[k]:
            ch=word_list1[i+1]
            i+=1
            for j in range(0,6):
                if ch==oper[j]:
                    fop=1
                    sop=ch
                    return 1
                #ungetc(ch,fp);
                return 1
                j+=1
        return 0;
        k+=1

def check(t):
    print t
    if numflag==1:
        print "\n number "+str(t)
        return
    for k in range(0,2):#(i=0;i<2;i++)
        if strcmp(t,predirect[k])==0:
            print "\n preprocessor directive "+str(t)
            return
    for k in range(0,6): #=0;i<6;i++)
        if strcmp(t,header[k])==0:
            print "\n header file "+str(t)
            return
    for k in range(0,21): #=0;i<21;i++)
        if strcmp(key[k],t)==0:
            print "\n keyword "+str(key[k])
            return
        print "\n identifier \t%s"+str(t)

def skipcomment():
    ch=word_list[i+1]
    i+=1
    if ch=='/':
        while word_list1[i]!='\0':
            i+=1#ch=getc(fp))!='\0':
    elif ch=='*':
        while f==0:
            ch=word_list1[i]
            i+=1
        if c=='/':
            f=1
    f=0




a=raw_input("Enter the file name:")
s=open(a,"r")
str1=s.read()
word_list1=str1.split()




i=0
#print word_list1[i]
for word in word_list1 :
    print word_list1[i]
    if word_list1[i]=="/":
        print word_list1[i]
    elif word_list1[i]==" ":
        print word_list1[i]
    elif word_list1[i].isalpha():
        if numflag!=1:
            token[j]=word_list1[i]
            j+=1
        if numflag==1:
            token[j]='\0'
            check(token)
            numflag=0
            j=0
            f=0
        if f==0:
            f=1
    elif word_list1[i].isalnum():
        if numflag==0:
            numflag=1
            token[j]=word_list1[i]
            j+=1
        else:
            if isdelim(word_list1[i]):
                if numflag==1:
                    token[j]='\0'
                    check(token)
                    numflag=0
                if f==1:
                    token[j]='\0'
                    numflag=0
                    check(token)
                j=0
                f=0
                print "\n delimiters : "+word_list1[i]
    elif isop(word_list1[i]):
        if numflag==1:
            token[j]='\0'
            check(token)
            numflag=0
            j=0
            f=0
        if f==1:
            token[j]='\0'
            j=0 
            f=0
            numflag=0
            check(token)    
        if fop==1:
            fop=0
            print "\n operator \t"+str(word_list1[i])+str(sop)
        else:
            print "\n operator \t"+str(c)
    elif word_list1[i]=='.':
        token[j]=word_list1[i]
        j+=1
    i+=1

3 个回答

0

看起来这个代码输出了很多内容,但逻辑有点难懂。我把它拿来自己跑了一遍,结果出错了,像这样:

Traceback (most recent call last):
  File "C:\dev\snippets\lexical.py", line 92, in <module>
    token[j]=word_list1[i]
IndexError: list assignment index out of range

老实说,这段代码写得不太好。你应该给函数起个更好的名字,而且不要用这种神秘的数字:

for k in range(0,14)

其实你已经有一个可以用来表示范围的列表了。

for k in range(delim)

这样稍微好理解一点。

不过你只是想判断c是否在列表delim里,所以直接说:

if c in delim

你为什么要返回1和0,这两个数字是什么意思?为什么不直接用True和False呢?

可能还有其他明显的问题,比如代码的“主”部分。

这段代码看起来不太符合Python的风格:

token=[0]*50

你真的只是想说这个吗?

token = []

现在它只是一个空列表。

与其像这样使用计数器:

token[j]=word_list1[i]

你应该像这样添加元素:

token.append (word_list[i])

老实说,我觉得你一开始就选了一个太难的问题。

1

你的代码写得不太好。试着把它拆分成更小的函数,这样你可以单独测试每个部分。你有没有尝试过调试程序?一旦找到导致问题的地方,你可以再回来这里问一个更具体的问题。

这里有一些额外的提示。你可以用更简单的方式来实现 isdelim,像这样:

def isdelim(c):
    return c in delim

要比较两个字符串是否相等,可以用 string1 == string2。在Python中没有 strcmp 这个函数。我不知道你是否知道,Python通常是解释执行的,而不是编译执行的。这意味着如果你调用一个不存在的函数,编译器不会报错。程序只会在运行时到达那个调用时才会出错。

在你的函数 isop 中,有一些代码是无法到达的。j += 1k += 1 这两行代码永远无法执行,因为它们在 return 语句之后。

在Python中,遍历一个集合是这样做的:

for item in collection:
    # do stuff with item

这些只是一些提示。你真的应该看看 Python教程

1
def isdelim(c):
    if c in delim:
        return 1
    return 0

你应该多了解一下Python的基础知识。目前,你的代码里有太多的iffor语句。

可以试着按照这个网站的方法来学习。

撰写回答