2010-10-22 21 views
0

Je crée un analyseur C Lexical en utilisant python dans le cadre du développement d'un analyseur.Voici mon code, j'ai écrit quelques méthodes pour identifier des mots-clés, nombres, opérateurs, etc .. Aucune erreur après la compilation. Pendant l'exécution, je pourrais entrer un fichier .c. Ma sortie devrait énumérer tous les mots-clés, identifiants, etc dans le fichier d'entrée. Mais ça ne montre rien. Peut-on m'aider avec ça. Le code est joint.C Analyseur lexical en 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

Wow. Quel travail pour réinventer la roue. Pourquoi ne pas télécharger 'ply' et commencer avec un analyseur de langage C existant? Pourquoi faire tout ça? –

+0

Je ne comprends pas pourquoi vous faites cela. Http://stackoverflow.com/questions/3976665/parser-generation, y compris une référence à un analyseur C complet en python, vous avez eu beaucoup de bons conseils sur votre question précédente (que je suppose être votre motivation). –

Répondre

1

Votre code est incorrect. Essayez de le diviser en fonctions plus petites que vous pouvez tester individuellement. Avez-vous essayé de déboguer le programme? Une fois que vous avez trouvé l'endroit qui cause le problème, vous pouvez revenir ici et poser une question plus précise.

Encore quelques conseils. Vous pouvez mettre en œuvre isdelim beaucoup plus simple comme ceci:

def isdelim(c): 
    return c in delim 

Pour comparer la chaîne pour l'égalité, utilisez string1 == string2. strcmp n'existe pas en Python. Je ne sais pas si vous êtes conscient que Python est généralement interprété et non compilé. Cela signifie que vous n'obtiendrez aucune erreur de compilation si vous appelez une fonction qui n'existe pas. Le programme se plaindra uniquement au moment de l'exécution lorsqu'il atteindra l'appel.

Dans votre fonction isop vous avez un code inaccessible. Les lignes j += 1 et k += 1 ne peuvent jamais être atteintes car elles sont exactes après une instruction return.

En Python itérer sur une collection se fait comme suit:

for item in collection: 
    # do stuff with item 

Ce ne sont que quelques conseils. Vous devriez vraiment lire le Python Tutorial.

+0

je suis nouveau en Python .. de toute façon thanx. – Aneeshia

+1

@Aneeshia: "je suis nouveau en Python". Cela signifie que vous ** devez ** lire le didacticiel Python en premier. Ensuite, après avoir lu le tutoriel, vous devriez Google pour "Python Lexical Scanning" et lire le code que vous y trouverez. Commencer avec un grand, mauvais morceau de code comme ceci est une mauvaise idée. Le tutoriel est une bonne idée. –

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

Vous devriez en apprendre plus sur les bases de Python. ATM, votre code contient trop if s et for s. Essayez l'apprentissage hard way.

0

Il semble que j'imprime pas mal de sortie, mais le code est assez difficile à suivre. Je l'ai couru contre lui-même et il a erré comme ça:

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 

Honnêtement, c'est assez mauvais code. Vous devez donner les fonctions meilleurs noms et ne pas utiliser les nombres magiques comme ceci:

for k in range(0,14) 

Je veux dire, vous avez déjà fait une liste que vous pouvez utiliser pour la gamme.

for k in range(delim) 

Rend un peu plus de sens.

Mais vous juste essayer de déterminer si c est dans la delim de liste, il suffit de dire:

if c in delim 

Pourquoi vous retournerez 1 et 0, que signifient-ils? Pourquoi ne pas utiliser Vrai et Faux.

Il existe probablement plusieurs autres problèmes évidents, comme toute la section "principale" du code.

Ce n'est pas très pythonique:

token=[0]*50 

Voulez-vous dire vraiment juste dire?

token = [] 

Maintenant c'est juste une liste vide.

Au lieu d'essayer d'utiliser un compteur comme ceci:

token[j]=word_list1[i] 

Vous voulez ajouter, comme ceci:

token.append (word_list[i]) 

Je pense sincèrement que vous avez commencé avec trop un problème.