C Лексический анализатор в Python - PullRequest
0 голосов
/ 22 октября 2010

Я создаю анализатор C Lexical, использующий 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

Ответы [ 3 ]

1 голос
/ 22 октября 2010
def isdelim(c):
    if c in delim:
        return 1
    return 0

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

Попробуйте научиться этому трудному пути .

1 голос
/ 22 октября 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 Tutorial .

0 голосов
/ 22 октября 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 в ограничителе списка, поэтому просто скажите:

if c in delim

Почему вы возвращаете 1 и 0, чтоони имеют в виду?Почему бы не использовать True и False.

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

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

token=[0]*50

Вы действительно просто хотите сказать?

token = []

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

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

token[j]=word_list1[i]

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

token.append (word_list[i])

Честно говоря, я думаю, что вы начали с слишком сложной проблемы.

...