2017-09-20 5 views
1

J'écris un analyseur syntaxique pour un format de fichier, et avoir un exemple que j'ai réduit à ce qui suit:Pourquoi cette grammaire pypars ne respecte-t-elle pas les fins de ligne?

import pyparsing as pp 

element = pp.OneOrMore(pp.Word(pp.alphas)) | pp.Literal("|") 
line = pp.Group(pp.OneOrMore(element)) + pp.White("\n") 
top_level = pp.OneOrMore(line) 

f = """ 
sdf dfg sdfgsdfsd | dsfgsdfsd sd sddffds safd | dfgdfg sadf | 
dsfg gdfg asdsad | gdfgdf dfgdfgdf sdf | dfgdfgdf | 
""" 

parse_result = top_level.parseString(f) 
print(parse_result.dump()) 

Cela donne:

[['sdf', 'dfg', 'sdfgsdfsd', '|', 'dsfgsdfsd', 'sd', 'sddffds', 'safd', '|', 'dfgdfg', 'sadf', '|', 'dsfg', 'gdfg', 'asdsad', '|', 'gdfgdf', 'dfgdfgdf', 'sdf', '|', 'dfgdfgdf', '|'], '\n'] 
[0]: 
    ['sdf', 'dfg', 'sdfgsdfsd', '|', 'dsfgsdfsd', 'sd', 'sddffds', 'safd', '|', 'dfgdfg', 'sadf', '|', 'dsfg', 'gdfg', 'asdsad', '|', 'gdfgdf', 'dfgdfgdf', 'sdf', '|', 'dfgdfgdf', '|'] 
[1]: 

Ce que je veux est pour chaque ligne de texte à apparaître comme un groupe séparé(), et il n'est pas clair pour moi pourquoi l'instruction pp.White("\n") ne correspond pas à la première (j'ai également essayé LineEnd(), avec le même résultat).

+2

pyparsing ignore l'espace entre les jetons par défaut. Les espaces blancs incluent les nouvelles lignes. – user2357112

+0

Oui, mais j'ai une expression spécifique pour correspondre à la nouvelle ligne. C'est ce qui me dérange. – u38cg

+0

Peu importe. Cela ne va pas l'empêcher de sauter des espaces pour correspondre à plus d'éléments. – user2357112

Répondre

2

Vous n'avez vraiment besoin que d'une ligne supplémentaire, impliquant ParserElement.setDefaultWhitespaceChars pour supprimer les nouvelles lignes comme l'un des caractères d'espace blanc par défaut. J'avale aussi les nouvelles lignes avec un suppress, comme ceci.

>>> import pyparsing as pp 
>>> pp.ParserElement.setDefaultWhitespaceChars(' \t') 
>>> element = pp.OneOrMore(pp.Word(pp.alphas)) | pp.Literal("|") 
>>> line = pp.Group(pp.OneOrMore(element)) + pp.White("\n").suppress() 
>>> top_level = pp.OneOrMore(line) 
>>> f = '''\ 
... sdf dfg sdfgsdfsd | dsfgsdfsd sd sddffds safd | dfgdfg sadf | 
... dsfg gdfg asdsad | gdfgdf dfgdfgdf sdf | dfgdfgdf | 
... ''' 

>>> r = top_level.parseString(f) 
>>> for item in r.asList(): 
...  item 
... 
['sdf', 'dfg', 'sdfgsdfsd', '|', 'dsfgsdfsd', 'sd', 'sddffds', 'safd', '|', 'dfgdfg', 'sadf', '|'] 
['dsfg', 'gdfg', 'asdsad', '|', 'gdfgdf', 'dfgdfgdf', 'sdf', '|', 'dfgdfgdf', '|']