gr_grs_parser.mly 23.3 KB
Newer Older
pj2m's avatar
pj2m committed
1 2
%{

bguillaum's avatar
bguillaum committed
3 4
open Grew_ast
open Grew_utils
pj2m's avatar
pj2m committed
5

6
(* Some intermediate sum types used in sub-functions when building the ast *)
pj2m's avatar
pj2m committed
7
type pat_item = 
bguillaum's avatar
bguillaum committed
8 9 10
  | Pat_node of Ast.node
  | Pat_edge of Ast.edge
  | Pat_const of Ast.const
pj2m's avatar
pj2m committed
11 12

type graph_item =
bguillaum's avatar
bguillaum committed
13 14
  | Graph_node of Ast.node
  | Graph_edge of Ast.edge
pj2m's avatar
pj2m committed
15 16 17 18 19

let get_loc () = (!Parser_global.current_file,!Parser_global.current_line+1)
let localize t = (t,get_loc ())
%}

20 21 22 23 24 25 26 27 28 29
%token LACC                        /* { */
%token RACC                        /* } */
%token LBRACKET                    /* [ */
%token RBRACKET                    /* ] */
%token LPAREN                      /* ( */
%token RPAREN                      /* ) */
%token DDOT                        /* : */
%token COMA                        /* , */
%token SEMIC                       /* ; */
%token STAR                        /* * */
bguillaum's avatar
bguillaum committed
30
%token PLUS                        /* + */
31 32 33 34 35 36 37 38 39 40 41
%token EQUAL                       /* = */
%token DISEQUAL                    /* <> */
%token PIPE                        /* | */
%token GOTO_NODE                   /* -> */
%token LTR_EDGE_LEFT               /* -[ */
%token LTR_EDGE_LEFT_NEG           /* -[^ */
%token LTR_EDGE_RIGHT              /* ]-> */
%token RTL_EDGE_LEFT               /* <-[ */
%token RTL_EDGE_RIGHT              /* ]- */
%token LONGARROW                   /* ==> */

42
%token INCLUDE                     /* include */
43
%token FEATURES                    /* features */
bguillaum's avatar
bguillaum committed
44 45
%token FEATURE                     /* feature */
%token FILE                        /* file */
46 47 48 49 50 51 52
%token LABELS                      /* labels */
%token MATCH                       /* match */
%token WITHOUT                     /* without */
%token COMMANDS                    /* commands */
%token MODULE                      /* module */
%token CONFLUENT                   /* confluent */
%token RULE                        /* rule */
bguillaum's avatar
bguillaum committed
53
%token LEX_RULE                    /* lex_rule */
54
%token FILTER                      /* filter */
55 56 57 58 59 60
%token SEQUENCES                   /* sequences */
%token GRAPH                       /* graph */

%token DEL_EDGE                    /* del_edge */
%token ADD_EDGE                    /* add_edge */
%token MERGE                       /* merge */
61 62
%token SHIFT_IN                    /* shift_in */
%token SHIFT_OUT                   /* shift_out */
63 64 65 66 67
%token SHIFT                       /* shift */
%token DEL_NODE                    /* del_node */
%token ADD_NODE                    /* add_node */
%token DEL_FEAT                    /* del_feat */

68 69
%token <string> PAT                /* $id */
%token <string> CMD                /* @id */
bguillaum's avatar
bguillaum committed
70

bguillaum's avatar
bguillaum committed
71
%token <string>           IDENT    /* indentifier */
72
%token <Grew_ast.Ast.qfn> QFN      /* ident.ident */
bguillaum's avatar
bguillaum committed
73 74 75
%token <string>           STRING
%token <int>              INT
%token <string list>      COMMENT
pj2m's avatar
pj2m committed
76

77
%token EOF                         /* end of file */
pj2m's avatar
pj2m committed
78

bguillaum's avatar
bguillaum committed
79 80 81
%start <Grew_ast.Ast.grs_with_include> grs_with_include
%start <Grew_ast.Ast.grs> grs
%start <Grew_ast.Ast.gr> gr
82
%start <Grew_ast.Ast.module_or_include list> included
pj2m's avatar
pj2m committed
83 84
%%

bguillaum's avatar
bguillaum committed
85 86 87 88 89 90 91 92 93 94 95

%public separated_list_final_opt(separator,X):
|                                                               { [] }
|   x=X                                                         { [x] }
|   x=X; separator; xs = separated_list_final_opt(separator,X)  { x :: xs }

%public separated_nonempty_list_final_opt(separator,X):
|   x=X                                                                  { [x] }
|   x=X; separator                                                       { [x] }
|   x=X; separator; xs = separated_nonempty_list_final_opt(separator,X)  { x :: xs }

pj2m's avatar
pj2m committed
96 97 98 99
/*=============================================================================================*/
/*  GREW GRAPH                                                                                 */
/*=============================================================================================*/

bguillaum's avatar
bguillaum committed
100 101


pj2m's avatar
pj2m committed
102
gr: 
bguillaum's avatar
bguillaum committed
103
        | GRAPH LACC items = separated_list_final_opt(SEMIC,gr_item) RACC EOF 
104 105
            {
             {
bguillaum's avatar
bguillaum committed
106 107
              Ast.nodes = List_.opt_map (function Graph_node n -> Some n | _ -> None) items;
              Ast.edges = List_.opt_map (function Graph_edge n -> Some n | _ -> None) items;
108 109
            }
           }
bguillaum's avatar
bguillaum committed
110

pj2m's avatar
pj2m committed
111
gr_item:
bguillaum's avatar
bguillaum committed
112
        | id = IDENT position = option(delimited(LPAREN,index,RPAREN)) feats = delimited(LBRACKET,separated_list_final_opt(COMA,node_features),RBRACKET) 
bguillaum's avatar
bguillaum committed
113
            { Graph_node (localize {Ast.node_id = id; position=position; fs=feats}) }
pj2m's avatar
pj2m committed
114

115
        | n1 = IDENT labels = delimited(LTR_EDGE_LEFT_NEG,separated_nonempty_list(PIPE,IDENT),LTR_EDGE_RIGHT) n2 = IDENT
bguillaum's avatar
bguillaum committed
116
            { Graph_edge (localize {Ast.edge_id = None; src=n1; edge_labels=labels; tar=n2; negative=true; }) }
pj2m's avatar
pj2m committed
117

118
        | n1 = IDENT labels = delimited(LTR_EDGE_LEFT,separated_nonempty_list(PIPE,IDENT),LTR_EDGE_RIGHT) n2 = IDENT
bguillaum's avatar
bguillaum committed
119
            { Graph_edge (localize {Ast.edge_id = None; src=n1; edge_labels=labels; tar=n2; negative=false; }) }
pj2m's avatar
pj2m committed
120 121

index:
122
        | INT { $1 }
pj2m's avatar
pj2m committed
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137










/*=============================================================================================*/
/*  GREW GRAPH SYSTEM REWRITING                                                                */
/*=============================================================================================*/


138 139 140
grs_with_include:
        | f = features_group g = global_labels m = module_or_include_list s = sequences EOF 
            {
bguillaum's avatar
bguillaum committed
141
             { Ast.domain_wi=f; 
142 143 144 145 146 147
               labels_wi=g; 
               modules_wi=m; 
               sequences_wi=s;
             }
           }
     
pj2m's avatar
pj2m committed
148
grs:
149 150
        | f = features_group g = global_labels m = modules s = sequences EOF 
            {
bguillaum's avatar
bguillaum committed
151
             { Ast.domain=f; 
152 153 154 155 156
               labels=g; 
               modules=m; 
               sequences=s;
             }
           }
157 158 159 160 161
       
module_or_include_list:
        | x = list(module_or_include) { x }

module_or_include:
bguillaum's avatar
bguillaum committed
162
        | m = grew_module        { Ast.Modul m }
163
        | INCLUDE sub = subfile SEMIC { Ast.Includ sub } 
pj2m's avatar
pj2m committed
164

165 166
subfile:
        | f = STRING  { localize f }
pj2m's avatar
pj2m committed
167 168 169 170 171 172 173 174 175 176 177 178 179 180

/*=============================================================================================*/
/*                                                                                             */
/* FEATURES DOMAIN DEFINITION                                                                  */
/*                                                                                             */
/* features {                                                                                  */
/*      cat: n, np, v, adj;                                                                    */
/*      mood: inf, ind, subj, pastp, presp;                                                    */
/*      lemma: *; phon: *                                                                      */
/* }                                                                                           */
/*                                                                                             */
/*=============================================================================================*/

features_group:
181 182
        | FEATURES x = features { x }
        
pj2m's avatar
pj2m committed
183
%inline features:
bguillaum's avatar
bguillaum committed
184 185
        | LACC x = separated_nonempty_list_final_opt(SEMIC,feature) RACC { x }

186
        
pj2m's avatar
pj2m committed
187
%inline feature:
188 189 190
        | name = feature_name DDOT values = features_values 
            { 
              if List.length values == 1 && List.hd values = "*"
bguillaum's avatar
bguillaum committed
191 192
              then Ast.Open name 
              else Ast.Closed (name,List.sort Pervasives.compare values)
193
            }
pj2m's avatar
pj2m committed
194 195

feature_name:
196
        | word = IDENT { word }
pj2m's avatar
pj2m committed
197 198

features_values:
199 200
        | STAR { ["*"] }
        | x = separated_nonempty_list(COMA,feature_value) { x }
pj2m's avatar
pj2m committed
201 202 203 204 205 206 207 208 209 210 211


/*=============================================================================================*/
/*                                                                                             */
/* GLOBAL LABELS DEFINITION                                                                    */
/*                                                                                             */
/* labels { OBJ, SUBJ, DE_OBJ, ANT }                                                           */
/*                                                                                             */
/*=============================================================================================*/

%inline labels:
bguillaum's avatar
bguillaum committed
212
        | x = delimited(LACC,separated_nonempty_list_final_opt(COMA,label),RACC) { x }
213
        
pj2m's avatar
pj2m committed
214
%inline label:
215
        | x = IDENT color = option(ddot_color)  { (x, color) }
pj2m's avatar
pj2m committed
216 217

ddot_color:
218
        | DDOT color = IDENT { color }
pj2m's avatar
pj2m committed
219 220

global_labels:
221
        | LABELS x = labels { x }
pj2m's avatar
pj2m committed
222 223 224 225 226 227 228 229 230 231 232 233


/*=============================================================================================*/
/*                                                                                             */
/* MODULE DEFINITION                                                                           */
/*                                                                                             */
/* module p7_to_p7p-mc {                                                                       */
/*   ...                                                                                       */
/* }                                                                                           */
/*                                                                                             */
/*=============================================================================================*/

234
included:
235
        | x = list (module_or_include) EOF { x }
236

pj2m's avatar
pj2m committed
237
modules:
238 239
        | x = list(grew_module) { x }
        
pj2m's avatar
pj2m committed
240
grew_module: 
241
        | doc = option(module_doc) MODULE conf = boption(CONFLUENT) id = module_id LACC l = option(local_labels) r = rules RACC 
242 243
           {
            { Ast.module_id = fst id; 
bguillaum's avatar
bguillaum committed
244 245
              local_labels = (match l with None -> [] | Some x -> x);
              rules = r;
246
              confluent = conf;
bguillaum's avatar
bguillaum committed
247
              module_doc = (match doc with Some d -> d | None -> []);
248 249
              mod_loc = (!Parser_global.current_file, snd id);
              mod_dir = "";
250 251
            }
          }
pj2m's avatar
pj2m committed
252 253

module_id:
254
        | id = IDENT { (id,!Parser_global.current_line+1) }
pj2m's avatar
pj2m committed
255 256

module_doc:
257
        | comment = COMMENT { comment } 
pj2m's avatar
pj2m committed
258 259 260 261 262 263 264 265 266 267 268 269

/*=============================================================================================*/
/*                                                                                             */
/* LOCAL LABELS DEFINITION                                                                     */
/*                                                                                             */
/* labels {ANT_TMP}                                                                            */
/*                                                                                             */
/*=============================================================================================*/



local_labels:
270
        | LABELS x = labels { x }
pj2m's avatar
pj2m committed
271 272 273 274 275 276 277 278 279 280 281 282


/*=============================================================================================*/
/*                                                                                             */
/* RULES DEFINITION                                                                            */
/*                                                                                             */
/* rule ant_prorel_init {                                                                      */
/*   ...                                                                                       */
/* }                                                                                           */
/*=============================================================================================*/

rules:
283
        | r = list(rule) { r }
pj2m's avatar
pj2m committed
284 285

rule: 
286 287
        | doc = option(rule_doc) RULE id = rule_id LACC p = pos_item n = list(neg_item) cmds = commands RACC 
            { 
bguillaum's avatar
bguillaum committed
288
              { Ast.rule_id = fst id;
289 290
                pos_pattern = p;
                neg_patterns = n;
bguillaum's avatar
bguillaum committed
291
                commands = cmds;
bguillaum's avatar
bguillaum committed
292
                param = None;
bguillaum's avatar
bguillaum committed
293
                rule_doc = begin match doc with Some d -> d | None -> [] end;
294 295 296
                rule_loc = (!Parser_global.current_file,snd id);
              }
            }         
bguillaum's avatar
bguillaum committed
297 298 299 300 301
        | doc = option(rule_doc) LEX_RULE id = rule_id param=option(param) LACC p = pos_item n = list(neg_item) cmds = commands RACC 
            { 
              { Ast.rule_id = fst id;
                pos_pattern = p;
                neg_patterns = n;
bguillaum's avatar
bguillaum committed
302
                commands = cmds;
bguillaum's avatar
bguillaum committed
303
                param = param;
bguillaum's avatar
bguillaum committed
304
                rule_doc = begin match doc with Some d -> d | None -> [] end;
bguillaum's avatar
bguillaum committed
305 306 307
                rule_loc = (!Parser_global.current_file,snd id);
              }
            }         
308 309 310 311 312 313 314
        | doc = option(rule_doc) FILTER id = rule_id LACC p = pos_item n = list(neg_item) RACC 
            { 
              { Ast.rule_id = fst id;
                pos_pattern = p;
                neg_patterns = n;
                commands = [];
                param = None;
bguillaum's avatar
bguillaum committed
315
                rule_doc = begin match doc with Some d -> d | None -> [] end;
316 317 318 319
                rule_loc = (!Parser_global.current_file,snd id);
              }
            }
 
bguillaum's avatar
bguillaum committed
320 321 322 323 324 325 326
param:
        | LPAREN FEATURE vars = separated_nonempty_list(COMA,var) SEMIC FILE file=STRING RPAREN { (file,vars) }

var:
        | i = PAT {i}
        | i = CMD {i}

pj2m's avatar
pj2m committed
327
pos_item:
328
        | MATCH i = pn_item { i }
pj2m's avatar
pj2m committed
329 330

neg_item:
331 332
        | WITHOUT i = pn_item { i }
          
pj2m's avatar
pj2m committed
333
pn_item: 
bguillaum's avatar
bguillaum committed
334
        | l = delimited(LACC,separated_nonempty_list_final_opt(SEMIC,pat_item),RACC)
335 336
            {
             {
bguillaum's avatar
bguillaum committed
337 338 339
              Ast.pat_nodes = List_.opt_map (function Pat_node n -> Some n | _ -> None) l;
              Ast.pat_edges = List_.opt_map (function Pat_edge n -> Some n | _ -> None) l;
              Ast.pat_const = List_.opt_map (function Pat_const n -> Some n | _ -> None) l;
340 341 342
            }
           }
        
pj2m's avatar
pj2m committed
343
rule_id:
344
        | id = IDENT { (id,!Parser_global.current_line+1) }
pj2m's avatar
pj2m committed
345 346

rule_doc:
347 348
        | comment = COMMENT { comment } 
        
pj2m's avatar
pj2m committed
349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364
/*=============================================================================================*/
/*                                                                                             */
/* MATCH DEFINITION                                                                            */
/*                                                                                             */
/* match {                                                                                     */
/*      P [cat = prorel];                                                                      */
/*      N -> P;                                                                                */
/*                                                                                             */
/*      without { P -[ANT]-> * }                                                               */
/*      without { P -[ANT_TMP]-> * }                                                           */
/*    }                                                                                        */
/*                                                                                             */
/*=============================================================================================*/


pat_item:
365 366 367
        | n = pat_node { Pat_node n }
        | e = pat_edge { Pat_edge e }
        | c = pat_const { Pat_const c }
pj2m's avatar
pj2m committed
368

369
pat_node:
bguillaum's avatar
bguillaum committed
370
        | id = IDENT feats = delimited(LBRACKET,separated_list_final_opt(COMA,node_features),RBRACKET) 
bguillaum's avatar
bguillaum committed
371
            { localize ({Ast.node_id = id; position=None; fs= feats}) }
pj2m's avatar
pj2m committed
372 373 374 375 376




node_features:
377
        | name = IDENT EQUAL STAR 
bguillaum's avatar
bguillaum committed
378
            { localize {Ast.kind = Ast.Disequality []; name=name; } } 
379
        | name = IDENT EQUAL values = separated_nonempty_list(PIPE,feature_value) 
bguillaum's avatar
bguillaum committed
380
            { localize {Ast.kind = Ast.Equality values; name=name; } } 
381
        | name = IDENT DISEQUAL values = separated_nonempty_list(PIPE,feature_value) 
bguillaum's avatar
bguillaum committed
382 383 384
            { localize {Ast.kind = Ast.Disequality values; name=name; } } 
        | name = IDENT EQUAL p = PAT
            { localize {Ast.kind = Ast.Param p; name=name; } } 
pj2m's avatar
pj2m committed
385 386

feature_value:
387 388
        | v = IDENT { v }
        | v = STRING { v }
389
        | v = INT { string_of_int v }
pj2m's avatar
pj2m committed
390

391
pat_edge:
392
        (* "e: A -> B" OR "e: A -[*]-> B" *)
393
        | id = edge_id n1 = IDENT GOTO_NODE n2 = IDENT
bguillaum's avatar
bguillaum committed
394
        | id = edge_id n1 = IDENT LTR_EDGE_LEFT_NEG STAR LTR_EDGE_RIGHT n2 = IDENT
bguillaum's avatar
bguillaum committed
395
               { localize ({Ast.edge_id = Some id; src=n1; edge_labels=[]; tar=n2; negative=true}) }
396 397 398

        (* "A -> B" *)
        | n1 = IDENT GOTO_NODE n2 = IDENT
bguillaum's avatar
bguillaum committed
399
               { localize ({Ast.edge_id = None; src=n1; edge_labels=[]; tar=n2; negative=true}) }
400 401 402

        (* "e: A -[^X|Y]-> B" *)
        | id = edge_id n1 = IDENT labels = delimited(LTR_EDGE_LEFT_NEG,separated_nonempty_list(PIPE,IDENT),LTR_EDGE_RIGHT) n2 = IDENT
bguillaum's avatar
bguillaum committed
403
            { localize ({Ast.edge_id = Some id; src=n1; edge_labels=labels; tar=n2; negative=true}) }
404 405 406
            
        (* "A -[^X|Y]-> B"*)
        | n1 = IDENT labels = delimited(LTR_EDGE_LEFT_NEG,separated_nonempty_list(PIPE,IDENT),LTR_EDGE_RIGHT) n2 = IDENT
bguillaum's avatar
bguillaum committed
407
            { localize ({Ast.edge_id = None; src=n1; edge_labels=labels; tar=n2; negative=true}) }
pj2m's avatar
pj2m committed
408

409 410
        (* "e: A -[X|Y]-> B" *)
        | id = edge_id n1 = IDENT labels = delimited(LTR_EDGE_LEFT,separated_nonempty_list(PIPE,IDENT),LTR_EDGE_RIGHT) n2 = IDENT
bguillaum's avatar
bguillaum committed
411
            { localize ({Ast.edge_id = Some id; src=n1; edge_labels=labels; tar=n2; negative=false}) }       
pj2m's avatar
pj2m committed
412

413 414
        (* "A -[X|Y]-> B" *)
        | n1 = IDENT labels = delimited(LTR_EDGE_LEFT,separated_nonempty_list(PIPE,IDENT),LTR_EDGE_RIGHT) n2 = IDENT
bguillaum's avatar
bguillaum committed
415
            { localize ({Ast.edge_id = None; src=n1; edge_labels=labels; tar=n2; negative=false}) }
pj2m's avatar
pj2m committed
416 417 418


edge_id:
419 420
        | id = IDENT DDOT { id }
                
pj2m's avatar
pj2m committed
421

422
pat_const:
bguillaum's avatar
bguillaum committed
423
        (* "A -[X|Y]-> *" *)
424
        | n1 = IDENT labels = delimited(LTR_EDGE_LEFT,separated_nonempty_list(PIPE,IDENT),LTR_EDGE_RIGHT) STAR
bguillaum's avatar
bguillaum committed
425
            { localize (Ast.Start (n1,labels)) }
bguillaum's avatar
bguillaum committed
426 427 428

        (* "A -> *" *)
        | n1 = IDENT GOTO_NODE STAR
bguillaum's avatar
bguillaum committed
429
            { localize (Ast.Cst_out n1) }
bguillaum's avatar
bguillaum committed
430 431

        (* "* -[X|Y]-> A" *)
432
        | STAR labels = delimited(LTR_EDGE_LEFT,separated_nonempty_list(PIPE,IDENT),LTR_EDGE_RIGHT) n2 = IDENT
bguillaum's avatar
bguillaum committed
433
            { localize (Ast.End (n2,labels)) }
pj2m's avatar
pj2m committed
434

bguillaum's avatar
bguillaum committed
435 436
        (* "* -> A" *)
        | STAR GOTO_NODE n2 = IDENT
bguillaum's avatar
bguillaum committed
437
            { localize (Ast.Cst_in n2) }
pj2m's avatar
pj2m committed
438

439
        | qfn1 = QFN EQUAL qfn2 = QFN
bguillaum's avatar
bguillaum committed
440
            { localize (Ast.Feature_eq (qfn1, qfn2)) }
441

pj2m's avatar
pj2m committed
442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468
/*=============================================================================================*/
/*                                                                                             */
/* COMMANDS DEFINITION                                                                         */
/*                                                                                             */
/* commands {                                                                                  */
/*      del_edge A -[OBJ]-> B;                                                                 */
/*      del_edge e;                                                                            */
/*                                                                                             */
/*      add_edge A -[ATS]-> B;                                                                 */
/*                                                                                             */
/*      shift A ==> B;                                                                         */
/*                                                                                             */
/*      del_node A;                                                                            */
/*                                                                                             */
/*      add_node D: <-[SUJ]- A;                                                                */
/*                                                                                             */
/*      A.mood = inf;                                                                          */
/*                                                                                             */
/*      B.tense = A.tense;                                                                     */
/*                                                                                             */
/*      del_feat A.tense;                                                                      */
/* }                                                                                           */
/*                                                                                             */
/*=============================================================================================*/


commands:
bguillaum's avatar
bguillaum committed
469
        | COMMANDS x = delimited(LACC,separated_nonempty_list_final_opt(SEMIC,command),RACC) { x }
pj2m's avatar
pj2m committed
470 471

command:
472
        | DEL_EDGE n = IDENT
bguillaum's avatar
bguillaum committed
473
            { localize (Ast.Del_edge_name n) }
474
        | DEL_EDGE n1 = IDENT label = delimited(LTR_EDGE_LEFT,IDENT,LTR_EDGE_RIGHT) n2 = IDENT 
bguillaum's avatar
bguillaum committed
475
            { localize (Ast.Del_edge_expl (n1,n2,label)) }
476
        | ADD_EDGE n1 = IDENT label = delimited(LTR_EDGE_LEFT,IDENT,LTR_EDGE_RIGHT) n2 = IDENT
bguillaum's avatar
bguillaum committed
477
            { localize (Ast.Add_edge (n1,n2,label)) }
478
        | SHIFT_IN n1 = IDENT LONGARROW n2 = IDENT 
bguillaum's avatar
bguillaum committed
479
            { localize (Ast.Shift_in (n1,n2)) }
480
        | SHIFT_OUT n1 = IDENT LONGARROW n2 = IDENT 
bguillaum's avatar
bguillaum committed
481
            { localize (Ast.Shift_out (n1,n2)) }
482
        | SHIFT n1 = IDENT LONGARROW n2 = IDENT 
bguillaum's avatar
bguillaum committed
483
            { localize (Ast.Shift_edge (n1,n2)) }
484
        | MERGE n1 = IDENT LONGARROW n2 = IDENT 
bguillaum's avatar
bguillaum committed
485
            { localize (Ast.Merge_node (n1,n2)) }
bguillaum's avatar
bguillaum committed
486
        | DEL_NODE n = IDENT
bguillaum's avatar
bguillaum committed
487
            { localize (Ast.Del_node n) }
488
        | ADD_NODE n1 = IDENT DDOT label = delimited(RTL_EDGE_LEFT,IDENT,RTL_EDGE_RIGHT) n2 = IDENT 
bguillaum's avatar
bguillaum committed
489
            { localize (Ast.New_neighbour (n1,n2,label)) }
490
        | DEL_FEAT qfn = QFN 
bguillaum's avatar
bguillaum committed
491
            { localize (Ast.Del_feat qfn) }
492
        | qfn = QFN EQUAL items = separated_nonempty_list (PLUS, concat_item)
bguillaum's avatar
bguillaum committed
493
            { localize (Ast.Update_feat (qfn, items)) }
494 495

concat_item:
496 497
        | qfn = QFN    { Ast.Qfn_item qfn }
        | s = IDENT    { Ast.String_item s }
bguillaum's avatar
bguillaum committed
498
        | s = STRING   { Ast.String_item s }
499
        | p = CMD      { Ast.Param_item p }
bguillaum's avatar
bguillaum committed
500
        | p = PAT      { Ast.Param_item p }
pj2m's avatar
pj2m committed
501 502 503 504 505 506 507 508 509 510

/*=============================================================================================*/
/*                                                                                             */
/* SEQUENCE DEFINITION                                                                         */
/*                                                                                             */
/* sequence { ant; p7_to_p7p-mc}                                                               */
/*                                                                                             */
/*=============================================================================================*/

sequences:
511
        | SEQUENCES seq = delimited(LACC,list(sequence),RACC) { seq }
pj2m's avatar
pj2m committed
512 513

sequence:
bguillaum's avatar
bguillaum committed
514
        | doc = option(COMMENT) id = sequence_id mod_names = delimited(LACC,separated_list_final_opt(SEMIC,IDENT),RACC) 
515 516
            { 
              { Ast.seq_name = fst id; 
bguillaum's avatar
bguillaum committed
517
                seq_mod = mod_names ; 
bguillaum's avatar
bguillaum committed
518
                seq_doc = begin match doc with Some d -> d | None -> [] end; 
519 520 521
                seq_loc = (!Parser_global.current_file,snd id);
              } 
            }
pj2m's avatar
pj2m committed
522 523

sequence_id:
524
        | id = IDENT { (id,!Parser_global.current_line+1) }
pj2m's avatar
pj2m committed
525 526

%%