C Лексический анализатор на питоне

Я создаю лексический анализатор C, используя python как часть разработки синтаксического анализатора. Здесь в моем коде я написал несколько методов для определения ключевых слов, чисел, операторов и т. д. После компиляции не отображается ошибка. Во время выполнения я мог бы ввести файл .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

person Aneeshia    schedule 22.10.2010    source источник
comment
Ух ты. Сколько работы, чтобы заново изобрести велосипед. Почему бы не загрузить ply и не начать с существующего анализатора языка C? Зачем все это?   -  person S.Lott    schedule 22.10.2010
comment
Я не понимаю, зачем ты это делаешь. У вас было много хороших советов по вашему предыдущему вопросу (который, как я полагаю, является вашей мотивацией) поколение, включая ссылку на полный синтаксический анализатор C в python.   -  person Ira Baxter    schedule 22.10.2010


Ответы (3)


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

Вам следует больше узнать об основах Python. ATM, ваш код содержит слишком много if и for.

Попробуйте изучить его сложным способом.

person N 1.1    schedule 22.10.2010

Ваш код плохой. Попробуйте разделить его на более мелкие функции, которые вы можете протестировать по отдельности. Пробовали отлаживать программу? Как только вы найдете место, которое вызывает проблему, вы можете вернуться сюда и задать более конкретный вопрос.

Еще несколько советов. Вы можете реализовать isdelim намного проще:

def isdelim(c):
    return c in delim

Чтобы сравнить строку на равенство, используйте string1 == string2. strcmp не существует в Python. Я не знаю, знаете ли вы, что Python обычно интерпретируется, а не компилируется. Это означает, что вы не получите ошибки компилятора, если вызовете несуществующую функцию. Программа будет жаловаться только во время выполнения, когда достигнет вызова.

В вашей функции isop у вас недостижимый код. Строки j += 1 и k += 1 никогда не могут быть достигнуты, так как они находятся сразу после оператора return.

В Python перебор коллекции выполняется следующим образом:

for item in collection:
    # do stuff with item

Это лишь некоторые подсказки. Вам действительно следует прочитать учебник по Python.

person Björn Pollex    schedule 22.10.2010
comment
я новичок в Python .. в любом случае, спасибо. - person Aneeshia; 22.10.2010
comment
@Aneeshia: я новичок в Python. Это означает, что вы должны сначала прочитать руководство по Python. Затем, после прочтения руководства, вам следует поискать в Google лексическое сканирование Python и прочитать код, который вы там найдете. Начинать с такого большого и плохого кода — плохая идея. Учебник - хорошая идея. - person S.Lott; 22.10.2010

Кажется, он выводит довольно много вывода для меня, но коду довольно сложно следовать. Я запустил его против самого себя, и он выдал ошибку следующим образом:

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.

Вероятно, есть несколько других явно очевидных проблем, таких как весь «основной» раздел кода.

Это не очень питонично:

token=[0]*50

Ты действительно хочешь сказать?

token = []

Теперь это просто пустой список.

Вместо того, чтобы пытаться использовать такой счетчик:

token[j]=word_list1[i]

Вы хотите добавить, например:

token.append (word_list[i])

Я искренне думаю, что вы начали со слишком сложной задачи.

person jgritty    schedule 22.10.2010