2009-11-11 22 views
2

J'essaie d'implémenter un analyseur python en utilisant PLY pour le langage Kconfig utilisé pour générer les options de configuration pour le noyau Linux.plusieurs lexeurs pour un parseur avec PLY?

Il y a un mot-clé source appelé qui effectue une inclusion, donc ce que je fais est que lorsque le lexer rencontre ce mot-clé, je change l'état lexer pour créer une nouvelle lexer qui va lex le fichier d'origine:

def t_begin_source(t): 
    r'source ' 
    t.lexer.begin('source') 

def t_source_path(t): 
    r'[^\n]+\n+' 
    t.lexer.begin('INITIAL') 
    global path 
    source_lexer = lex.lex(errorlog=lex.NullLogger()) 
    source_file_name = (path + t.value.strip(' \"\n')) 
    sourced_file = file(path + t.value.strip(' \"\n')).read() 

    source_lexer.input(sourced_file) 

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

ailleurs j'ai cette ligne

lexer = lex.lex(errorlog=lex.NullLogger()) 

Ceci est le lexer « principal » ou « root » qui va être appelé par l'analyseur.

Mon problème est que je ne sais pas comment dire l'analyseur d'utiliser un lexer différent ou de dire la « source_lexer » pour retourner quelque chose ...

Peut-être la fonction clone doit être utilisé ...

Merci

Répondre

2

Je ne sais pas les détails de PLI, mais dans d'autres systèmes comme celui-ci que je l'ai construit, il a fait le plus de sens d'avoir un seul lexer qui a géré la pile d'inclure des fichiers. Le lexeur renvoie donc un flux unifié de jetons, en ouvrant et en fermant les fichiers d'inclusion au fur et à mesure qu'ils sont rencontrés.

+0

Vous pouvez utiliser la méthode 'input' de la lexer pour réinitialiser le lexer et fournir une nouvelle entrée. Après le fichier inclus est fait, vous devez revenir au fichier d'origine où vous avez laissé (plus ou moins.) –

+0

oui, mais je ne sais pas comment retourner ces jetons à l'analyseur. – LB40

0

Ok,

donc ce que je l'ai fait est la construction d'une liste de tous les jetons, qui est construit avant l'analyse réelle.

L'analyseur n'appelle plus le lexeur car vous pouvez remplacer la fonction getToken utilisée par l'analyseur en utilisant le paramètre tokenfunc lors de l'appel de la fonction d'analyse.

result = yacc.parse(kconfig,debug=1,tokenfunc=my_function) 

et ma fonction qui est maintenant la fonction appelée pour obtenir les itère prochaine jeton sur la liste des jetons précédemment construits. Considérant le lexing, quand je rencontre un mot-clé source, je clone mon lexer et change l'entrée pour inclure le fichier.

def sourcing_file(source_file_name): 
    print "SOURCE FILE NAME " , source_file_name 
    sourced_file = file(source_file_name).read() 
    source_lexer = lexer.clone() 
    source_lexer.input(sourced_file) 
    print 'END OF SOURCING FILE' 

    while True: 
     tok = source_lexer.token() 
     if not tok: 
      break 
     token_list.append(tok) 
2

Par une coïncidence intéressante un lien de la même recherche Google qui m'a conduit à cette question explique comment write your own lexer for a PLY parser. Le message explique simplement et bien, mais c'est une question de quatre variables d'instance et une seule méthode token.

+0

Je l'ai fait aussi ... mais finalement, la solution de construire une liste complète de jeton et d'utiliser ma propre fonction getToken n'était pas si mauvaise ... – LB40