2010-07-24 19 views
4

J'essaye de construire un simple lexer/analyseur avec Alex/Happy dans Haskell, et je voudrais garder certaines informations de localisation du fichier texte dans mon finale AST.Comment garder plusieurs valeurs sémantiques pendant l'analyse avec Happy/Haskell

j'ai réussi à construire un lexer en utilisant Alex qui Dressez une liste de tokens avec localisation:

data Token = Token AlexPosn Foo Bar 
lexer :: String -> [Token] 

dans mon dossier Heureux, lors de la déclaration de la% partie symbolique, je déclare ce sont la partie sémantique de le jeton avec le symbole $$

%token FOO { Token _ $$ _ } 

et dans la règle d'analyse, le $ i se référera à ce $$.

foo_list: FOO { [$1] } 
     | foo_list FOO { $2 : $1 } 

Est-il possible de se référer à la partie AlexPosn et à la partie Foo du FOO jeton? En ce moment je ne sais comment faire référence à un seul d'entre eux. Je peux trouver des informations sur un moyen d '"ajouter plusieurs $$", et de s'y référer après.

Existe-t-il un moyen de le faire?

V.

+0

En fait, cela ne semble pas possible même dans le C flex/bison, donc il ne devrait pas être possible directement dans haskell ou caml. Cependant, je pourrais utiliser un tuple data Token = Token (AlexPosn, Foo, Bar)) au lieu de plusieurs arguments. Je laisse la question ouverte pendant quelques jours mais je pense que je la fermerai bientôt. – Vinz

Répondre

4

En fin de compte, je ne trouve 2 solutions:

  • pack

    toutes les données de sens dans un tuple, de sorte que le point à ce $$ tuple, puis extraire les données par projection:

    data Token = Token (AlexPosn,Foo) Bar 
    %token FOO { Token $$ some_bar } 
    rule : FOO { Ast (fst $1) (snd $1) } 
    
  • ne pas utiliser $$ du tout: si vous ne l'utilisez $$, heureux vous donnera le jeton lors de l'analyse, il vous appartient d'extraire wha t vous avez vraiment besoin de ce jeton:

    data Token = Token AlexPosn Foo Bar 
    %token FOO = { Token _ _ some_bar } 
    rule : FOO { Ast (get_pos $1) (get_foo $1) } 
    
    get_pos :: Token -> AlexPosn 
    get_foo :: Token -> Foo 
    

    ...

Je pense que le premier est le plus élégant. Le second peut être assez lourd en termes de lignes de code si vous transportez beaucoup d'informations: vous devrez construire des "projections" à la main (appariement de motifs et ainsi de suite), et le faire de manière sûre peut être difficile si votre type de jeton est assez grand.

+1

+1 pour répondre à votre propre question - cela m'a sauvé beaucoup de tracas! – Jack

+0

Oui, merci beaucoup. –