2017-10-15 7 views
0

J'ai un problème avec mon analyseur lexical construit avec PLY.Erreur avec la nouvelle ligne sur Lex - Python

Lorsque je passe le code d'une boucle for à mon programme, le saut de ligne entre { et } n'est pas reconnu. Au lieu de cela, une erreur est signalée, même s'il existe une fonction t_newline(t).

L'entrée au programme est:

for(int i = 0 ; i < 5 ; i++){ 
} 

Et, la sortie du programme est

1 . analizadorLexico.py 
2 . analizadorSintactico.py 
3 . parser.out 
4 . parsetab.py 
5 . prueba1.txt 
6 . cpp.py 
7 . ctokens.py 
8 . lex.py 
9 . yacc.py 
10 . ygen.py 
11 . __init__.py 
12 . lex.cpython-36.pyc 
13 . yacc.cpython-36.pyc 
14 . __init__.cpython-36.pyc 
15 . analizadorLexico.cpython-36.pyc 
16 . parsetab.cpython-36.pyc 

File number: 5 
5 
Escogido el archivoprueba1.txt 
LexToken(FOR,'FOR',1,0) 
LexToken(PA,'(',1,3) 
LexToken(INT,'INT',1,4) 
LexToken(ID,'i',1,8) 
LexToken(ASSIGN,'=',1,10) 
LexToken(NUMBER,0,1,12) 
LexToken(END,';',1,14) 
LexToken(ID,'i',1,16) 
LexToken(LT,'<',1,18) 
LexToken(NUMBER,5,1,20) 
LexToken(END,';',1,22) 
LexToken(ID,'i',1,24) 
LexToken(PLUS,'+',1,25) 
LexToken(PLUS,'+',1,26) 
LexToken(PC,')',1,27) 
LexToken(CA,'{',1,28) 
Error in ' 
' 
LexToken(CC,'}',2,31) 

Le code est:

reservados = ['FOR','AND','OR','NOT','XOR', 'INT', 'FLOAT', 'DOUBLE', 
'SHORT','LONG', 'BOOL'] 
tokens = reservados + [ 
     'ID', 
     'NUMBER', 
     'PLUS', 
     'MINUS', 
     'TIMES', 
     'DIVIDE', 
     'DIVE', 
     'ASSIGN', 
     'LT', 
     'MA', 
     'LTE', 
     'MAE', 
     'DIF', 
     'PA', 
     'PC', 
     'ANDC', 
     #'ORC', 
     'NOTC', 
     'MOD', 
     'CMP', 
     'END', 
     'COMMA', 
     'CA', 
     'CC', 
     #'ES' 

] 
t_ignore = ' \t' 
t_ignore_WHITESPACES = r'[ \t]+' 
t_PLUS = r'\+' 
t_MINUS = r'-' 
t_TIMES = r'\*' 
t_DIVIDE = r'/' 
t_ASSIGN = r'=' 
t_LT = r'<' 
t_MA = r'>' 
t_LTE = r'<=' 
t_MAE = r'>=' 
t_DIF = r'\!=' 
t_PA = r'\(' 
t_PC = r'\)' 
t_ANDC = r'\&&' 
#t_ORC = r'\||' 
t_NOTC = r'\!' 
t_DIVE = r'\\' 
t_MOD = r'\%' 
t_CMP = r'==' 
t_END = r'\;' 
t_COMMA = r'\,' 
t_CA = r'{' 
t_CC = r'}' 
#t_ES = r'\ ' 

def t_newline(t): 
    r'\n+' 
    t.lexer.lineno += len(t.value) 

def t_ID(t): 
    r'[a-zA-Z_][a-zA-Z0-9_]*' 
    """ 
     CONVIERTE CUALQUIER IDENTIFICADOR EN MAYUSCULA EN CASO DE QUE SE 
     HAYA ESCRITO ASÍ 
    """ 
    if t.value.upper() in reservados: 
     t.value = t.value.upper() 
     t.type = t.value 

    return t 

def t_NUMBER(t): 
    r'\d+' 
    t.value = int(t.value)  
    return t 

def t_error(t): 
    print ("Error de sintaxis '%s'" % t.value[0]) 
    t.lexer.skip(1) 


def buscarFicheros(directorio): 
    ficheros = [] 

    numArchivo = '' 
    respuesta = False 
    cont = 1 

    for dirName, subdirList, fileList in os.walk(directorio): 
     #print('Directorio encontrado: %s' % dirName) 
     for fname in fileList: 
      ficheros.append(fname) 

    for file in ficheros: 
     print ("",cont,".",file) 
     cont = cont + 1 

    while respuesta == False: 
     numArchivo = input('\nNumero del archivo: ') 
     print (numArchivo) 
     for file in ficheros: 
      if file == ficheros[int(numArchivo) - 1]: 
       respuesta = True 
       break 

    print ("Escogido el archivo" + ficheros[int(numArchivo) - 1]) 
    return ficheros[int(numArchivo) - 1] 

directorio = r'C:/Users/Carlos/Desktop/for c++/' 
archivo = buscarFicheros(directorio) 
test = directorio + archivo 

fp = codecs.open(test, "r", "utf-8") 
cadena = fp.read() 
fp.close() 

analizador = lex.lex() 
analizador.input(cadena) 

while True: 
    tok = analizador.token() 
    if not tok : break 
    print (tok) 

Merci pour votre aide

+0

Est-ce que 't_newline' doit retourner' t'? – snakecharmerb

+0

Non @snakecharmerb, cette fonction ne devrait rien retourner, si elle retourne une exception – ElPapu

+0

Comment 't_newline' est-il transmis à l'objet' analizador'? – snakecharmerb

Répondre

0

Je pense que le m L'explication la plus probable est que l'erreur est causée par la fin de ligne de Windows \r\n. \r n'est pas dans votre liste de caractères à ignorer, mais aucune règle ne le gère donc il va déclencher une erreur. Si c'est le problème, la solution la plus simple est d'ajouter \r à t_ignore. (Je ne vois aucun intérêt à avoir à la fois t_ignore et t_ignore_WHITESPACES, donc je vous suggère de supprimer l'un d'entre eux.)

Cependant, je ne peux pas reproduire la sortie d'erreur que vous fournissez. Le code dans votre message ne semble pas avoir de fonction qui pourrait sortir la chaîne Error in '..., donc cela pourrait simplement être le résultat du collage de la sortie d'une version différente du code.