2017-10-15 109 views
0

我用PLY构建的词法分析器出现问题。Lex上新行出现错误 - Python

当我将for循环的代码传递给我的程序时,无法识别{}之间的换行符。相反,即使存在t_newline(t)函数,也会报告错误。

输入到程序是:

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

而且,该程序的输出是

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) 

的代码:

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) 

感谢您的帮助

+0

't_newline'应该返回't'吗? – snakecharmerb

+0

否@scharcharmerb,如果返回异常,此函数不应返回任何内容 – ElPapu

+0

如何将't_newline'传递给'analizador'对象? – snakecharmerb

回答

0

我觉得米最可能的解释是该错误是由Windows行结尾\r\n引起的。 \r不在您要忽略的字符列表中,但没有规则处理它,因此它会触发错误。

如果这是问题,最简单的解决方案是将\r添加到t_ignore。 (我没有看到有任何一点同时有t_ignoret_ignore_WHITESPACES,所以我建议你删除其中的一个。)

但是,我无法重现您提供的错误输出。您帖子中的代码似乎没有任何可能会输出字符串Error in '...的函数,所以这可能只是粘贴来自不同版本代码的输出的结果。