fmt and some rewrite of expressions
This commit is contained in:
parent
dc34c9f194
commit
2f05f7ba09
1 changed files with 125 additions and 133 deletions
|
@ -36,9 +36,13 @@ program:
|
||||||
|
|
||||||
definition:
|
definition:
|
||||||
/* Définition de types */
|
/* Définition de types */
|
||||||
// Manque le 'type_variable located list' ici, on met une liste vide en attendant
|
| TYPE tc=located(type_constructor) tvl=optionlist(definition_typevariablelist)
|
||||||
| TYPE tc=located(type_constructor) EQUAL td=tdefinition {
|
EQUAL td=tdefinition {
|
||||||
DefineType (tc, [], td)
|
DefineType (tc, tvl, td)
|
||||||
|
}
|
||||||
|
// La tdefinition peut être optionnel, dans ce cas on utilise c'est abstrait
|
||||||
|
| TYPE tc=located(type_constructor) tvl=optionlist(definition_typevariablelist) {
|
||||||
|
DefineType (tc, tvl, Abstract)
|
||||||
}
|
}
|
||||||
/* Valeurs externes */
|
/* Valeurs externes */
|
||||||
| EXTERN id=located(identifier) ts=located(type_scheme) {
|
| EXTERN id=located(identifier) ts=located(type_scheme) {
|
||||||
|
@ -49,11 +53,16 @@ definition:
|
||||||
DefineValue v
|
DefineValue v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
definition_typevariablelist:
|
||||||
|
| INFERIOR l=separated_nonempty_list(COMMA, located(type_variable)) SUPERIOR {
|
||||||
|
l
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
tdefinition:
|
tdefinition:
|
||||||
/* Type sommes */
|
/* Type sommes */
|
||||||
/* la définition étant assez compliqué, on va utilisé d'autre terme pour réduire la taille */
|
/* la définition étant assez compliqué, on va utilisé d'autre terme pour réduire la taille */
|
||||||
| option(PIPE) l=separated_nonempty_list(PIPE,list_constructor_and_ty) {
|
| option(PIPE) l=separated_nonempty_list(PIPE, list_constructor_and_their_ty) {
|
||||||
DefineSumType(l)
|
DefineSumType(l)
|
||||||
}
|
}
|
||||||
/* Type produit étiqueté */
|
/* Type produit étiqueté */
|
||||||
|
@ -61,15 +70,17 @@ tdefinition:
|
||||||
DefineRecordType(lt)
|
DefineRecordType(lt)
|
||||||
}
|
}
|
||||||
|
|
||||||
list_constructor_and_ty: c=located(constructor) t=list_ty{
|
list_constructor_and_their_ty:
|
||||||
|
// TODO: C'est pas sensé être en option list_ty ici?
|
||||||
|
| c=located(constructor) t=list_ty {
|
||||||
(c, t)
|
(c, t)
|
||||||
}
|
}
|
||||||
|
|
||||||
list_ty: LPAREN l=separated_nonempty_list(COMMA,located(ty)) RPAREN {
|
list_ty:
|
||||||
|
| LPAREN l=separated_nonempty_list(COMMA, located(ty)) RPAREN {
|
||||||
l
|
l
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
label_with_type:
|
label_with_type:
|
||||||
| l=located(label) COLON t=located(ty) {
|
| l=located(label) COLON t=located(ty) {
|
||||||
l, t
|
l, t
|
||||||
|
@ -96,7 +107,8 @@ vdef_type_scheme:
|
||||||
|
|
||||||
|
|
||||||
fundef:
|
fundef:
|
||||||
| COLON t=option(located(type_scheme)) i=located(identifier) p=located(pattern) EQUAL e=located(expression) {
|
| COLON t=option(located(type_scheme)) i=located(identifier) p=located(pattern)
|
||||||
|
EQUAL e=located(expression) {
|
||||||
i, t, FunctionDefinition(p, e)
|
i, t, FunctionDefinition(p, e)
|
||||||
}
|
}
|
||||||
| i=located(identifier) p=located(pattern) EQUAL e=located(expression) {
|
| i=located(identifier) p=located(pattern) EQUAL e=located(expression) {
|
||||||
|
@ -110,10 +122,7 @@ fundef:
|
||||||
* TODO : y'a environ 50 warnings ici, surtout au niveau du POr et PAnd */
|
* TODO : y'a environ 50 warnings ici, surtout au niveau du POr et PAnd */
|
||||||
|
|
||||||
branches:
|
branches:
|
||||||
| b=separated_nonempty_list(PIPE, located(branch)) {
|
| option(PIPE) b=separated_nonempty_list(PIPE, located(branch)) {
|
||||||
b
|
|
||||||
}
|
|
||||||
| PIPE b=separated_nonempty_list(PIPE, located(branch)) {
|
|
||||||
b
|
b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,24 +157,37 @@ simple_pattern:
|
||||||
| const=located(constructor) {
|
| const=located(constructor) {
|
||||||
PTaggedValue(const, None, [])
|
PTaggedValue(const, None, [])
|
||||||
}
|
}
|
||||||
| const=located(constructor) INFERIOR liste_ty=option(separated_nonempty_list(COMMA, located(ty))) SUPERIOR {
|
| const=located(constructor)
|
||||||
|
INFERIOR liste_ty=option(separated_nonempty_list(COMMA, located(ty))) SUPERIOR {
|
||||||
PTaggedValue(const, liste_ty, [])
|
PTaggedValue(const, liste_ty, [])
|
||||||
}
|
}
|
||||||
| const=located(constructor) LPAREN liste_pattern=separated_nonempty_list(COMMA, located(pattern)) RPAREN {
|
| const=located(constructor)
|
||||||
|
LPAREN liste_pattern=separated_nonempty_list(COMMA, located(pattern)) RPAREN {
|
||||||
PTaggedValue(const, None, liste_pattern)
|
PTaggedValue(const, None, liste_pattern)
|
||||||
}
|
}
|
||||||
| const=located(constructor) INFERIOR liste_ty=option(separated_nonempty_list(COMMA, located(ty))) SUPERIOR LPAREN liste_pattern=separated_nonempty_list(COMMA, located(pattern)) RPAREN {
|
| const=located(constructor)
|
||||||
|
INFERIOR liste_ty=option(separated_nonempty_list(COMMA, located(ty))) SUPERIOR
|
||||||
|
LPAREN liste_pattern=separated_nonempty_list(COMMA, located(pattern)) RPAREN {
|
||||||
PTaggedValue(const, liste_ty, liste_pattern)
|
PTaggedValue(const, liste_ty, liste_pattern)
|
||||||
}
|
}
|
||||||
/* Enregistrement */
|
/* Enregistrement */
|
||||||
/* à refaire */
|
/* à refaire */
|
||||||
| LBRACE l=separated_nonempty_list(COMMA, separated_pair(located(label), EQUAL, located(pattern))) RBRACE {
|
| LBRACE l=separated_nonempty_list(
|
||||||
|
COMMA,
|
||||||
|
separated_pair(located(label), EQUAL, located(pattern))
|
||||||
|
) RBRACE {
|
||||||
PRecord(l, None)
|
PRecord(l, None)
|
||||||
}
|
}
|
||||||
| LBRACE l=separated_nonempty_list(COMMA, separated_pair(located(label), EQUAL, located(pattern))) RBRACE INFERIOR SUPERIOR {
|
| LBRACE l=separated_nonempty_list(
|
||||||
|
COMMA,
|
||||||
|
separated_pair(located(label), EQUAL, located(pattern))
|
||||||
|
) RBRACE INFERIOR SUPERIOR {
|
||||||
PRecord(l, None)
|
PRecord(l, None)
|
||||||
}
|
}
|
||||||
| LBRACE l=separated_nonempty_list(COMMA, separated_pair(located(label), EQUAL, located(pattern))) RBRACE INFERIOR liste_ty=option(separated_nonempty_list(COMMA, located(ty))) SUPERIOR {
|
| LBRACE l=separated_nonempty_list(
|
||||||
|
COMMA,
|
||||||
|
separated_pair(located(label), EQUAL, located(pattern))
|
||||||
|
) RBRACE INFERIOR liste_ty=option(separated_nonempty_list(COMMA, located(ty))) SUPERIOR {
|
||||||
PRecord(l, liste_ty)
|
PRecord(l, liste_ty)
|
||||||
}
|
}
|
||||||
/* Disjonction */
|
/* Disjonction */
|
||||||
|
@ -182,7 +204,8 @@ pattern_and:
|
||||||
| p1=simple_pattern{
|
| p1=simple_pattern{
|
||||||
p1
|
p1
|
||||||
}
|
}
|
||||||
| p1=located(simple_pattern) AND p_list=separated_nonempty_list(AND, located(simple_pattern)) {
|
| p1=located(simple_pattern)
|
||||||
|
AND p_list=separated_nonempty_list(AND, located(simple_pattern)) {
|
||||||
PAnd(p1 :: p_list)
|
PAnd(p1 :: p_list)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,7 +230,9 @@ simple_ty:
|
||||||
| tc=type_constructor {
|
| tc=type_constructor {
|
||||||
TyCon(tc, [])
|
TyCon(tc, [])
|
||||||
}
|
}
|
||||||
| tc=type_constructor INFERIOR liste_ty=separated_nonempty_list(COMMA, located(ty)) SUPERIOR {
|
/* 'liste_ty' doit etre optionnel => gérer par le cas au dessus */
|
||||||
|
| tc=type_constructor
|
||||||
|
INFERIOR liste_ty=separated_nonempty_list(COMMA, located(ty)) SUPERIOR {
|
||||||
TyCon(tc, liste_ty)
|
TyCon(tc, liste_ty)
|
||||||
}
|
}
|
||||||
/* Variables de type */
|
/* Variables de type */
|
||||||
|
@ -237,7 +262,8 @@ ty:
|
||||||
|
|
||||||
type_scheme:
|
type_scheme:
|
||||||
/* Il faut peut être modifié le séparateur */
|
/* Il faut peut être modifié le séparateur */
|
||||||
| LBRACK liste_typevar=separated_list(COMMA, located(type_variable)) RBRACK ty=located(ty) {
|
| LBRACK liste_typevar=separated_list(COMMA, located(type_variable))
|
||||||
|
RBRACK ty=located(ty) {
|
||||||
ForallTy(liste_typevar, ty)
|
ForallTy(liste_typevar, ty)
|
||||||
}
|
}
|
||||||
| ty=located(ty) {
|
| ty=located(ty) {
|
||||||
|
@ -247,167 +273,134 @@ type_scheme:
|
||||||
|
|
||||||
/********************************* EXPRESSION *********************************/
|
/********************************* EXPRESSION *********************************/
|
||||||
|
|
||||||
/* De manière générale, il faudrait au mieux revoir le code, pour le factoriser et le rendre plus propre */
|
|
||||||
/* (il y a même moyen que ça le soit obligatoire pour pas avoir des conflits éventuel) */
|
|
||||||
/* Exemple : TAgged et Record, trop de cas différent alors qu'on pourrait en faire en 2 fois au moins voir 1 */
|
|
||||||
simple_expression:
|
simple_expression:
|
||||||
/* Simple litteral */
|
/* Simple litteral */
|
||||||
| l=located(literal) {
|
| l=located(literal) {
|
||||||
Literal l
|
Literal l
|
||||||
}
|
}
|
||||||
/* Variable */
|
/* Variable */
|
||||||
| i=located(identifier) {
|
| i=located(identifier) tl=option(type_list) {
|
||||||
Variable(i, None)
|
Variable(i, tl)
|
||||||
}
|
|
||||||
| i=located(identifier) INFERIOR SUPERIOR {
|
|
||||||
Variable(i, None)
|
|
||||||
}
|
|
||||||
| i=located(identifier) INFERIOR t_list=option(separated_nonempty_list(COMMA, located(ty))) SUPERIOR {
|
|
||||||
Variable(i, t_list)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Tuple n = 0 and n > 1 */
|
/* Tuple n = 0 and n > 1 - Construction d'un 0-uplet */
|
||||||
| LPAREN RPAREN {
|
| LPAREN RPAREN {
|
||||||
Tuple([])
|
Tuple([])
|
||||||
}
|
}
|
||||||
| LPAREN e=located(expression) COMMA e_list=separated_nonempty_list(COMMA, located(expression)) RPAREN {
|
/* Tuple n > 1 - Construction d'un n-uplet (n > 1) */
|
||||||
Tuple(e::e_list)
|
| el=expr_list {
|
||||||
|
Tuple(el)
|
||||||
}
|
}
|
||||||
|
/* Tagged Value - Construction d'une donnée */
|
||||||
/* Tagged Value*/
|
| const=located(constructor) tl=option(type_list) el=optionlist(expr_list) {
|
||||||
/* K */
|
Tagged(const, tl, el)
|
||||||
| const=located(constructor) {
|
|
||||||
Tagged(const, None, [])
|
|
||||||
}
|
}
|
||||||
/* K < > */
|
/* Record - Construction d'un enregistrement */
|
||||||
| const=located(constructor) INFERIOR SUPERIOR {
|
| LBRACE l=separated_nonempty_list(
|
||||||
Tagged(const, None, [])
|
COMMA,
|
||||||
|
separated_pair(located(label), EQUAL, located(expression))
|
||||||
|
) RBRACE tl=option(type_list) {
|
||||||
|
Record(l, tl)
|
||||||
}
|
}
|
||||||
/* K < > (e1, ..., en) */
|
/* Lecture de variable
|
||||||
| const=located(constructor) INFERIOR SUPERIOR LPAREN e_list=separated_nonempty_list(COMMA, located(expression)) RPAREN {
|
* !expr */
|
||||||
Tagged(const, None, e_list)
|
|
||||||
}
|
|
||||||
/* K <ty_1, ... ty_m> */
|
|
||||||
| const=located(constructor) INFERIOR t_list=option(separated_nonempty_list(COMMA, located(ty))) SUPERIOR {
|
|
||||||
Tagged(const, t_list, [])
|
|
||||||
}
|
|
||||||
/* K <ty_1, ..., ty_m> (e1, ..., en) */
|
|
||||||
| const=located(constructor) INFERIOR t_list=option(separated_nonempty_list(COMMA, located(ty))) SUPERIOR LPAREN e_list=separated_nonempty_list(COMMA, located(expression)) RPAREN {
|
|
||||||
Tagged(const, t_list, e_list)
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Record */
|
|
||||||
| LBRACE l=separated_nonempty_list(COMMA, separated_pair(located(label), EQUAL, located(expression))) RBRACE {
|
|
||||||
Record(l, None)
|
|
||||||
}
|
|
||||||
| LBRACE l=separated_nonempty_list(COMMA, separated_pair(located(label), EQUAL, located(expression))) RBRACE INFERIOR SUPERIOR {
|
|
||||||
Record(l, None)
|
|
||||||
}
|
|
||||||
| LBRACE l=separated_nonempty_list(COMMA, separated_pair(located(label), EQUAL, located(expression))) RBRACE INFERIOR t_list=option(separated_nonempty_list(COMMA, located(ty))) SUPERIOR {
|
|
||||||
Record(l, t_list)
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Lecture de variable */
|
|
||||||
/* ! expr */
|
|
||||||
| EXCLA e=located(simple_expression) {
|
| EXCLA e=located(simple_expression) {
|
||||||
Read(e)
|
Read(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type_list:
|
||||||
|
| INFERIOR tl=optionlist(separated_nonempty_list(COMMA, located(ty))) SUPERIOR {
|
||||||
|
tl
|
||||||
|
}
|
||||||
|
|
||||||
|
expr_list:
|
||||||
|
| LPAREN el=separated_nonempty_list(COMMA, located(expression)) RPAREN {
|
||||||
|
el
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
expression:
|
expression:
|
||||||
| e=simple_expression {
|
| e=simple_expression {
|
||||||
e
|
e
|
||||||
}
|
}
|
||||||
/* Field */
|
/* Field - Projection d’un champ */
|
||||||
|
| e=located(expression) DOT l=located(label) tl=option(type_list) {
|
||||||
/* e.l */
|
Field(e, l, tl)
|
||||||
| e=located(expression) DOT l=located(label) {
|
|
||||||
Field(e, l, None)
|
|
||||||
}
|
}
|
||||||
/* e.l < > */
|
/* Sequence - Séquencement *
|
||||||
| e=located(expression) DOT l=located(label) INFERIOR SUPERIOR {
|
* Pas sûr, voir s'il ne fuat pas une troisième couche d'expression */
|
||||||
Field(e, l, None)
|
| e=located(simple_expression)
|
||||||
}
|
SEMICOLON e_list=separated_nonempty_list(SEMICOLON, located(simple_expression)) {
|
||||||
/* e.l <ty_1...ty_n>*/
|
|
||||||
| e=located(expression) DOT l=located(label) INFERIOR t_list=option(separated_nonempty_list(COMMA, located(ty))) SUPERIOR {
|
|
||||||
Field(e, l, t_list)
|
|
||||||
}
|
|
||||||
/* Sequence */
|
|
||||||
/* Pas sûr, voir s'il ne fuat pas une troisième couche d'expression */
|
|
||||||
| e=located(simple_expression) SEMICOLON e_list=separated_nonempty_list(SEMICOLON, located(simple_expression)) {
|
|
||||||
Sequence(e :: e_list)
|
Sequence(e :: e_list)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Definition locale */
|
/* Definition locale */
|
||||||
| vd=vdefinition SEMICOLON e=located(expression) {
|
| vd=vdefinition SEMICOLON e=located(expression) {
|
||||||
Define(vd, e)
|
Define(vd, e)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fonction anonyme */
|
/* Fonction anonyme */
|
||||||
| BACKSLASH p=located(pattern) ARROW e=located(expression) {
|
| BACKSLASH p=located(pattern) ARROW e=located(expression) {
|
||||||
Fun(FunctionDefinition(p, e))
|
Fun(FunctionDefinition(p, e))
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Application */
|
/* Application */
|
||||||
| e1=located(expression) e2=located(expression) {
|
| e1=located(expression) e2=located(expression) {
|
||||||
Apply(e1, e2)
|
Apply(e1, e2)
|
||||||
}
|
}
|
||||||
|
/* Operateurs binaires - Application infixe */
|
||||||
|
/* | e1=located(expression) b=binop e2=located(expression) {
|
||||||
/* Match (exp) {| ...| ... | ...} */
|
Apply(Apply(b, e1), e2)
|
||||||
|
} */
|
||||||
|
/* Analyse de motifs
|
||||||
|
* match (exp) {| ...| ... | ...} */
|
||||||
| MATCH LPAREN e=located(expression) RPAREN LBRACE b=branches RBRACE {
|
| MATCH LPAREN e=located(expression) RPAREN LBRACE b=branches RBRACE {
|
||||||
Case(e, b)
|
Case(e, b)
|
||||||
}
|
}
|
||||||
|
/* Conditionnelle (1)
|
||||||
/* TODO if ( exp ) then { expr } j'ai RIEN COMPRIS */
|
* if ( expr ) then { expr } */
|
||||||
/* | IF LPAREN e=located(expression) RPAREN
|
| IF LPAREN e1=located(expression) RPAREN
|
||||||
THEN LBRACE e2=located(expression) RBRACE {
|
THEN LBRACE e2=located(expression) RBRACE {
|
||||||
IfThenElse(e, e2, None)
|
(* else { () } aka le 0-uplet *)
|
||||||
} */
|
IfThenElse(e1, e2, Position.unknown_pos (Tuple []))
|
||||||
|
}
|
||||||
/* if ( expr ) then { expr } else { expr } */
|
/* Conditionnelle (2)
|
||||||
| IF LPAREN e=located(expression) RPAREN
|
* if ( expr ) then { expr } else { expr } */
|
||||||
|
| IF LPAREN e1=located(expression) RPAREN
|
||||||
THEN LBRACE e2=located(expression) RBRACE
|
THEN LBRACE e2=located(expression) RBRACE
|
||||||
ELSE LBRACE e3=located(expression) RBRACE {
|
ELSE LBRACE e3=located(expression) RBRACE {
|
||||||
IfThenElse(e, e2, e3)
|
IfThenElse(e1, e2, e3)
|
||||||
}
|
}
|
||||||
|
/* Reference - Allocation
|
||||||
/* Reference ref expr */
|
* ref expr */
|
||||||
| REF e=located(expression) {
|
| REF e=located(expression) {
|
||||||
Ref(e)
|
Ref(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Affectation
|
/* Affectation
|
||||||
* expr := expr */
|
* expr := expr */
|
||||||
| e1=located(expression) ASSIGN e2=located(expression) {
|
| e1=located(expression) ASSIGN e2=located(expression) {
|
||||||
Assign(e1, e2)
|
Assign(e1, e2)
|
||||||
}
|
}
|
||||||
|
/* While - Boucle non bornée
|
||||||
/* While */
|
* while ( expr ) { expr } */
|
||||||
/* while ( expr ) { expr } */
|
| WHILE LPAREN e1=located(expression) RPAREN
|
||||||
| WHILE LPAREN e=located(expression) RPAREN
|
|
||||||
LBRACE e2=located(expression) RBRACE {
|
LBRACE e2=located(expression) RBRACE {
|
||||||
While(e, e2)
|
While(e1, e2)
|
||||||
}
|
}
|
||||||
|
/* Do while - Boucle non bornée et non vide
|
||||||
/* Do while
|
|
||||||
* do { expr } until ( expr ) */
|
* do { expr } until ( expr ) */
|
||||||
/* TODO */
|
| DO LBRACE e1=located(expression) RBRACE UNTIL LPAREN e2=located(expression) RPAREN {
|
||||||
|
Sequence([e2 ; Position.unknown_pos (While(e1, e2))])
|
||||||
/* Boucle for
|
}
|
||||||
|
/* Boucle for - Boucle bornée
|
||||||
* for x in (e1 to e2) { expr } */
|
* for x in (e1 to e2) { expr } */
|
||||||
| FOR x=located(identifier)
|
| FOR var=located(identifier)
|
||||||
FROM LPAREN e1=located(expression) RPAREN TO LPAREN e2=located(expression) RPAREN
|
FROM LPAREN e1=located(expression) RPAREN TO LPAREN e2=located(expression) RPAREN
|
||||||
LBRACE e3=located(expression) RBRACE {
|
LBRACE e3=located(expression) RBRACE {
|
||||||
For(x, e1, e2, e3)
|
For(var, e1, e2, e3)
|
||||||
}
|
}
|
||||||
|
/* Parenthésage
|
||||||
/* Parenthésage pas sûr mais je vois pas sinon */
|
* Pas sûr mais je vois pas sinon */
|
||||||
| LPAREN e=expression RPAREN {
|
| LPAREN e=expression RPAREN {
|
||||||
e
|
e
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Annotation de type
|
/* Annotation de type
|
||||||
* (e : ty) */
|
* (e : ty) */
|
||||||
| LPAREN e=located(expression) COLON t=located(ty) RPAREN {
|
| LPAREN e=located(expression) COLON t=located(ty) RPAREN {
|
||||||
|
@ -415,14 +408,6 @@ expression:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Operateurs binaires */
|
|
||||||
/* | e1=located(expression) b=binop e2=located(expression) {
|
|
||||||
Apply(Apply(b,e1),e2)
|
|
||||||
} */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/******************************** BASIC TYPES *********************************/
|
/******************************** BASIC TYPES *********************************/
|
||||||
|
@ -451,12 +436,15 @@ label:
|
||||||
|
|
||||||
|
|
||||||
literal:
|
literal:
|
||||||
|
/* Entier positif */
|
||||||
| i=INT {
|
| i=INT {
|
||||||
LInt i
|
LInt i
|
||||||
}
|
}
|
||||||
|
/* Caractère */
|
||||||
| c=CHAR {
|
| c=CHAR {
|
||||||
LChar c
|
LChar c
|
||||||
}
|
}
|
||||||
|
/* Chaîne de caractères */
|
||||||
| s=STRING {
|
| s=STRING {
|
||||||
LString s
|
LString s
|
||||||
}
|
}
|
||||||
|
@ -485,3 +473,7 @@ identifier:
|
||||||
%inline located(X): x=X {
|
%inline located(X): x=X {
|
||||||
Position.with_poss $startpos $endpos x
|
Position.with_poss $startpos $endpos x
|
||||||
}
|
}
|
||||||
|
|
||||||
|
%inline optionlist(X): x=option(X) {
|
||||||
|
match x with | Some l -> l | None -> []
|
||||||
|
}
|
||||||
|
|
Reference in a new issue