2017-04-06 7 views
0

Je travaille sur un analyseur de python en utilisant ply et je dois analyser l'entrée sous forme de:PLI: Caractère illégal « + »

VAR VAR1 001 
+000 000 000 000 

Lorsque le code créerait une variable nommée VAR 1 puis attribuez-lui la la valeur 0 à ce

le regex j'ai écrit pour l'instanciation est:

t_INST = r'[\+|-]0[ ][0-9][0-9][0-9][ ][0-9][0-9][0-9][ ][0-9][0-9][0-9][ ][0-9][0-9][0-9]' 

Cependant lors de l'exécution de mon programme, imprime PLY les éléments suivants:

Illegal character '+' 

A reproducer suit:

import ply.lex as lex 

tokens = ['INST'] 
t_INST = r'[+-]0[ ](\d{3}[ ]){3}\d{3}'; 
t_ignore = ' \t' 
def t_error(t): 
    print("Illegal character '%s'" % t.value[0]) 
    t.lexer.skip(1) 

lexer = lex.lex() 

def parse(input_string): 
    ret = [] 
    lexer.input (input_string) 
    while True: 
     tok = lexer.token() 
     if not tok: 
      break  # No more input 
     ret.append((tok.type, tok.value)) 
    return ret 

print parse("+0 000 000 000") 
+0

Vous devez utiliser \ d pour désigner les caractères et également utiliser {} pour désigner des séquences répéter: [\ + -] (: \ d {3} \ s? {4} – Neil

+0

Pourquoi le backslash? Vous voudriez cela dans un contexte normal, mais cela n'a pas de sens dans une classe de personnage.En fait, sauf si '|' est un premier caractère valide, vous voulez probablement '[+ -]', pas '[+ | -]', aussi. –

+0

BTW, il serait utile d'avoir votre reproducteur - tout en restant aussi * minimal * que possible - être étendu au point où il est * complet * et * vérifiable *, comme indiqué dans http://stackoverflow.com/ aide/mcve À l'heure actuelle, quelqu'un doit faire assez de travail pour reproduire le bogue. –

Répondre

0

La ligne:

print parse("+0 000 000 000") 

ne correspond pas à votre format d'entrée déclaré de

VAR VAR1 001 
+000 000 000 000 

Si la réelle données est dans la même forme que +0 000 000 000, alors vous voulez réellement:

t_INST = r'[+-]0\s(?:\d{3}\s){2}\d{3}' 

... dont la sortie est: [('INST', '+0 000 000 000')]

+0

C'est un peu la regex que j'ai donnée dans ma réponse en utilisant le '\ s' pour les raccourcis et les non-capturants. Cela ressemble plus à un commentaire pour ma question. De plus, vous avez utilisé '{2}' et devriez être '{3}' –

+0

Pour les données de test de l'OP, non, cela devrait vraiment être ** {2} '. Leurs commentaires sont trompeurs sur le format de données utilisé. (C'est pourquoi j'ai passé le temps à les harceler en fournissant un vrai reproducteur, au lieu d'écrire une réponse directement). –

1

Vous ne devez pas échapper + dans les classes de personnages. Vous pouvez utiliser:

t_INST = r'[+|-]0[ ][0-9][0-9][0-9][ ][0-9][0-9][0-9][ ][0-9][0-9][0-9][ ][0-9][0-9][0-9]' 
    this-----^ 

Quoi qu'il en soit, vous pouvez réduire votre regex comme ceci:

t_INST = r'[+|-]0[ ][0-9]{3}[ ][0-9]{3}[ ][0-9]{3}[ ][0-9]{3}' 

Ou encore:

t_INST = r'[+|-]0[ ]([0-9]{3}[ ]){3}[0-9]{3}' 

remarqué également que vous avez utilisé [+|-], ceci est une classe de caractère et ne fonctionne pas avec les alternances, vous devez donc le remplacer par [+-].

Ainsi, un regex final (en utilisant \d comme raccourci pour [0-9]) serait:

t_INST = r'[+-]0[ ](\d{3}[ ]){3}\d{3}' 

BTW, vous exemple de texte dit:

+000 000 000 000 

Mais l'expression rationnelle que vous utilisez matchs ceci:

+0 000 000 000 000 

Donc, si vous les données que vous voulez faire correspondre est +000 000 000 000, alors vous devez changer l'expression rationnelle:

t_INST = r'[+-](\d{3}[ ]){3}\d{3}' 
+0

... le problème ici (c'est-à-dire le mauvais comportement pour lequel j'ai choisi d'écrire une réponse concurrente plutôt que de commenter celle-ci) est que vous avez écrit une réponse sans réellement avoir un vrai reproducteur qui pourrait créer leur problème; donc sans aucune garantie que vous sachiez vraiment ce que le problème du PO était réellement. Même si 're.compile (r '[\ + | -]'). Match ('+')' ne fonctionnait pas, je serais d'accord qu'il y aurait de bonnes raisons de spéculer, mais ce n'est pas le cas ici: Le code original était * mauvais *, mais (testably!) Pas cassé sur aucun des motifs initialement donnés. –

+0

... en effet, 're.compile (r '[\ + | -] 0 [] [0-9] [0-9] [0-9] [] [0-9] [0-9] [ 0-9] [] [0-9] [0-9] [0-9] [] [0-9] [0-9] [0-9] '). Match (' + 0 000 000 000 000 ') 'renvoie une correspondance. –