2011-09-17 8 views
5

Sto usando lo strato e ho notato una strana discrepanza tra la corrispondenza di token re memorizzata in t.lex.lexmatch, in confronto con uno sre_pattern definito nel solito modo con il re modulo. Il gruppo (x) 's sembrano essere fuori dal 1.espressione regolare di lexmatch ply ha gruppi diversi rispetto al solito re

Ho definito un semplice lexer per illustrare il comportamento che sto vedendo:

import ply.lex as lex 

tokens = ('CHAR',) 

def t_CHAR(t): 
    r'.' 
    t.value = t.lexer.lexmatch 
    return t 

l = lex.lex() 

(ottengo un avvertimento circa t_error ma ignorarlo per . ora) ora mi nutro qualche input nel lexer e ottenere un token:

l.input('hello') 
l.token() 

ottengo un LexToken(CHAR,<_sre.SRE_Match object at 0x100fb1eb8>,1,0). Voglio guardare un oggetto partita:

m = _.value 

Così ora guardo i gruppi:

m.group() =>'h' come mi aspetto.

m.group(0) =>'h' come previsto.

m.group(1) =>'h', tuttavia, mi aspetto che non abbia un tale gruppo.

confronta questo per la creazione di un'espressione così regolare manualmente:

import re 
p = re.compile(r'.') 
m2 = p.match('hello') 

Questo dà diversi gruppi:

m2.group() = 'h' come mi aspetto.

m2.group(0) = 'h' come previsto.

m2.group(1) fornisce IndexError: no such group come previsto.

Qualcuno sa perché questa discrepanza esiste?

risposta

4

Nella versione 3.4 di PLY, il motivo per cui questo si verifica è correlato al modo in cui le espressioni vengono convertite da docstring a pattern.

Guardando la fonte ha veramente di aiuto - la linea 746 di lex.py:

c = re.compile("(?P<%s>%s)" % (fname,f.__doc__), re.VERBOSE | self.reflags) 

non mi consiglia fare affidamento su qualcosa di simile tra le versioni - questo è solo parte della magia di come funziona PLY .

0

sembra per me che corrispondenza gruppo dipende dalla posizione della funzione di token nel file, come se i gruppi sono stati effettivamente cumulati attraverso tutti i gettoni regex dichiarati:

t_MYTOKEN1(t): 
     r'matchit(\w+)' 
     t.value = lexer.lexmatch.group(1) 
     return t 

    t_MYTOKEN2(t): 
     r'matchit(\w+)' 
     t.value = lexer.lexmatch.group(2) 
     return t