Domanda

Sto cercando di costruire un semplice lexer/parser con Alex/Happy in Haskell, e vorrei mantenere alcune informazioni di localizzazione dal file di testo nel mio AST finale.

Sono riuscito a creare un lexer utilizzando Alex che crea un elenco di token con localizzazione:

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

Nel mio file felice, quando si dichiara la parte del token %, posso dichiarare quali sono la parte semantica del token con il simbolo $$

%token FOO  { Token _ $$ _ }

e nella regola di analisi, $i si riferirà a questo $$.

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

C'è un modo per fare riferimento alla parte AlexPosn E alla parte Foo del token FOO?Al momento so solo come fare riferimento a uno solo di essi.Posso trovare informazioni su come "aggiungere diversi $$" e fare riferimento ad essi in seguito.

C'è un modo per farlo ?

V.

È stato utile?

Soluzione

Alla fine ho trovato 2 soluzioni:

  • Imballo tutti i dati significato in una tupla, in modo che $$ indichi questa tupla, quindi estrai i dati mediante proiezione:

    data Token = Token (AlexPosn,Foo) Bar
    %token FOO { Token $$ some_bar }
    rule : FOO  { Ast (fst $1) (snd $1) }
    
  • non usare affatto $$:se non usi $$, happy ti darà il token completo durante l'analisi, quindi spetta a te estrarre ciò di cui hai veramente bisogno da questo token:

    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
    

    ...

Penso che il primo sia il più elegante.Il secondo può essere piuttosto pesante in termini di righe di codice se si trasportano molte informazioni:dovrai costruire "proiezioni" a mano (corrispondenza di modelli e così via), e farlo in modo sicuro può essere complicato se il tuo tipo di token è piuttosto grande.

Altri suggerimenti

È anche possibile mantenere più valori come questo:

data Token = Token AlexPosn Foo Bar
%token FOO { Token pos foo some_bar }
rule : FOO { Ast pos foo }
.

Anche se non sono sicuro se felice realmente garantisce che questo funzionerà sempre.La ragione del perché (forse) funziona è che felice genererà il codice che il modello corrisponde a Token pos foo some_bar, rendendo disponibile pos e foo disponibile in Ast pos foo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top