2010-10-22 2 views
0

Я создаю C Лексический анализатор, использующий python как часть разработки парсера. В моем коде я написал несколько методов для определения ключевых слов, чисел, операторов и т. Д. После компиляции не отображается ошибка. Во время выполнения я мог ввести файл .c. Мой вывод должен отображать все ключевые слова, идентификаторы и т. Д. Во входном файле. Но это ничего не показывает. Может ли кто-нибудь помочь мне в этом. Код прилагается.C Лексический анализатор в python

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 
+0

Ничего себе. Какая много работы, чтобы изобретать велосипед. Почему бы не загрузить 'ply' и начать с существующего синтаксического анализа языка C? Зачем все это? –

+0

Я не понимаю, почему вы это делаете. У вас было много хороших советов по вашему предыдущему вопросу (который, как я полагаю, является вашей мотивацией) http://stackoverflow.com/questions/3976665/parser-generation, включая ссылку на полный парсер C в python. –

ответ

1

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

Еще несколько советов. Вы можете реализовать 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

Я новичок в Python .. в любом случае thanx. – Aneeshia

+1

@Aneeshia: «Я новичок в Python». Это означает, что вы ** должны ** сначала прочитать учебник Python. Затем, прочитав учебное пособие, вы должны использовать Google для «Лексического сканирования Python» и прочитать код, который вы там найдете. Начиная с большой, плохой части кода, такой, как плохая идея. Учебник - хорошая идея. –

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

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

Попробуйте изучить его hard way.

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) 

Имеет немного больше смысла.

Но вы просто пытаетесь определить, если с в списке DELIM, так просто сказать:

if c in delim 

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

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

Это не очень вещий:

token=[0]*50 

ли вы на самом деле просто хочу сказать?

token = [] 

Теперь это всего лишь пустой список.

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

token[j]=word_list1[i] 

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

token.append (word_list[i]) 

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