Forum Clubic

Ocaml lexer

Bonjour,

j’ai un fichier lexer.mll où j’ai des non terminaux comme

op = [’+’ ‘~’ '’]
id = ( [‘a’-‘z’]
| op )

mais si je parse un ‘+’ il sera considéré comme un op
comment faire pour qu’il soit considéré comme un op et comme un id?

Où bien alors si je ne peux pas faire la distinction dans le lexer comment faire dans mon parser.mly quand j’ai :

| x=ID {…}
sans avoir a dupliquer la règle
|x=ID {…}
|x=OP {…}

Merci

Je ne connais rien à ocaml, plus aux grammaires algébriques, mais pour moi, je ne mélangerai pas op et id. Je ferais deux tokens complétement séparés.

Par contre, est-ce que ton truc mélange règles du lexer et du parser ?

Nan j’ai deux fichiers distincts, l’un où j’ai mes regles du lexer :

op = [’+’ ‘~’ '’]
id = ( [‘a’-‘z’]
| op )

rule main = parse
| op as x { OP(x)}
| id as x { ID(x)}

Et le fichier parser.mly :

%token

|LPAR x=ID RPAR {…}

x=OP TRUC {…}

Si je separe les tokens je ne pourrais plus reconnaitre (+), et je ne peux pas dupliquer la regle parce que sa serait trop long après.

Si tu as un lexer, c’est pour séparer tes tokens de tes règles de parser. Pour le coup, je ne vois pas pourquoi tes symboles font partis de tes identifiants ?

Vu que je ne connais pas Caml, je vais le faire en pseudo-Java : j’espère que ça t’ira :slight_smile:

expr : expr '+' expr  {return new OperatorPlus($1, $3);}
       | expr '-' expr   {return new OperatorMoins($1, $3);}
       | '(' expr ')'        {return $2;}
       | T_IDENTIFIER  {return new Identifier($1.value);}

Il manque également la gestion correcte de l’associativité (ie: a + b - c donne-t’il (a+b)-c ou a+(b-c) ?).

Dans le lexer, tu dois retourner ‘+’, ‘~’, ‘*’, et pour [a-z]+ renvoyer T_IDENTIFIER avec la valeur lue, et ignorer complétement les espaces.