1/** 2 * Parser.jjt 3 * This file is part of JaCoP. 4 * 5 * JaCoP is a Java Constraint Programming solver. 6 * 7 * Copyright (C) 2000-2008 Krzysztof Kuchcinski and Radoslaw Szymanek 8 * 9 * This program is free software: you can redistribute it and/or modify 10 * it under the terms of the GNU Affero General Public License as published by 11 * the Free Software Foundation, either version 3 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU Affero General Public License for more details. 18 * 19 * Notwithstanding any other provision of this License, the copyright 20 * owners of this work supplement the terms of this License with terms 21 * prohibiting misrepresentation of the origin of this work and requiring 22 * that modified versions of this work be marked in reasonable ways as 23 * different from the original version. This supplement of the license 24 * terms is in accordance with Section 7 of GNU Affero General Public 25 * License version 3. 26 * 27 * You should have received a copy of the GNU Affero General Public License 28 * along with this program. If not, see <http://www.gnu.org/licenses/>. 29 * 30 */ 31 32/* ************************************************************ 33* JavaCC Options 34************************************************************ */ 35 36options { 37 STATIC = false; 38 NODE_PREFIX = "AST"; 39 MULTI = true; 40 NODE_DEFAULT_VOID = true; 41 NODE_PACKAGE = "org.jacop.fz"; 42} 43 44 45/* ************************************************************ 46* Parser Properties 47************************************************************ */ 48 49PARSER_BEGIN(Parser) 50package org.jacop.fz; 51 52import java.util.ArrayList; 53import org.jacop.core.Store; 54 55public class Parser { 56 Store store = new Store(); 57 Tables dict = new Tables(store); 58 VariablesParameters cg = new VariablesParameters(); 59 Constraints cc = new Constraints(store, dict); 60 Solve solver = new Solve(store, cc.sat); 61 Options options; 62 63 void setOptions(Options opt) { 64 options = opt; 65 } 66 67 Store getStore() { 68 return store; 69 } 70 71 Tables getTables() { 72 return dict; 73 } 74} 75PARSER_END(Parser) 76 77 78/************************************************************** 79* 80* Lexical Specification Starts 81* 82***************************************************************/ 83 84/* WHITE SPACE (Always Skipped) */ 85SKIP : 86{ 87 " " 88| "\t" 89| "\n" 90| "\r" 91| "\f" 92} 93 94/* COMMENTS (Default is Skip) */ 95SPECIAL_TOKEN : 96{ 97 <SINGLE_LINE_COMMENT: "%" (~["\n","\r"])* ("\n"|"\r"|"\r\n")> 98} 99 100/* LITERALS */ 101// string_literal \"[^"\n]*\" 102TOKEN : 103{ 104 < STRING_LITERAL : "\"" (~["\n", "\r", "\f"])* "\""> 105} 106 107// int_literal -?[0-9]+|-?0x[0-9A-Fa-f]+|-?0o[0-7]+ 108TOKEN : 109{ 110 < INT_LITERAL : (["-"])? (["0"-"9"])+ | (["-"])? "0x" (["0"-"9", "A"-"F", "a"-"f"])+ | 111 (["-"])? "0o" (["0"-"7"])+ > 112} 113 114//float_literal -?[0-9]+\.[0-9]+|-?[0-9]+\.[0-9]+[Ee][-+]?[0-9]+|-?[0-9]+[Ee][-+]?[0-9]+ 115TOKEN : 116{ 117 < FLOAT_LITERAL : ("-")? (["0"-"9"])+ "." (["0"-"9"])+ | 118 ("-")? (["0"-"9"])+ "." (["0"-"9"])+ ("E" | "e") ("-" | "+")? (["0"-"9"])+ | 119 ("-")? (["0"-"9"])+ ("E" | "e") ("-" | "+")? (["0"-"9"])+ > 120} 121 122/* SEPARATORS */ 123TOKEN : 124{ 125 < SC: ";" > 126| < COLON: ":" > 127| < COMMA: "," > 128} 129 130/* DELIMETERS */ 131TOKEN : 132{ 133 < LP: "(" > 134| < RP: ")" > 135| < LBOX: "[" > 136| < RBOX: "]" > 137| < LB: "{" > 138| < RB: "}" > 139} 140 141/* OPERATORS */ 142TOKEN : 143{ 144 < ASGN: "=" > 145} 146 147 148/* Reserved words */ 149TOKEN : 150{ 151 < ARRAY: "array" > 152 | < BOOL: "bool" > 153 | < CONSTRAINT: "constraint" > 154 | < FALSE: "false" > 155 | < FLOAT: "float" > 156 | < INT: "int" > 157 | < MINIMIZE: "minimize" > 158 | < MAXIMIZE: "maximize" > 159 | < OF: "of" > 160 | < OUTPUT: "output" > 161 | < PREDICATE: "predicate" > 162 | < SATISFY: "satisfy" > 163 | < SET: "set" > 164 | < SHOW: "show" > 165 | < SHOW_COND: "show_cond" > 166 | < SOLVE: "solve" > 167 | < TRUE: "true" > 168 | < VAR: "var" > 169 | < DOTDOT: ".." > 170 | < COLONCOLON: "::"> 171} 172 173/* IDENTIFIER */ 174// ident [A-Za-z][A-Za-z0-9_]* 175TOKEN : 176{ 177 < IDENT: (["_"])* ["a"-"z", "A"-"Z"] (["a"-"z", "A"-"Z", "0"-"9", "_"])* > 178 // | < VAR_PAR_ID: (["_"])* ["a"-"z", "A"-"Z"] (["a"-"z", "A"-"Z", "0"-"9", "_"])* > 179 // | < PRED_ANN_ID: ["a"-"z", "A"-"Z"] (["a"-"z", "A"-"Z", "0"-"9", "_"])* > 180} 181 182/************************************************************** 183* 184* GRAMMER STARTS 185* 186***************************************************************/ 187 188//--------------------------------------------------------------------------- 189// Model top-level 190//--------------------------------------------------------------------------- 191 192// model : pred_decl_items var_decl_items constraint_items model_end 193 194void model() #model: 195{} 196{ 197 { cc.setOptions(options); cg.setOptions(options); solver.startTimer();} 198 pred_decl_items() 199 var_decl_items() 200 constraint_items() 201 model_end() 202 <EOF> 203 {//jjtThis.dump(""); 204 // print debug information 205 // if (options.debug()) 206 // System.out.println(dict); 207 dict.removeAliasFromSearch(); 208 209 // generate constraints 210 cc.generateAllConstraints(jjtThis); 211 // search 212 solver.solveModel(jjtThis, dict, options); 213 } 214} 215 216// pred_decl_items : pred_decl_items pred_decl_item ';' 217// | pred_decl_items error ';' { yyerrok; } 218// | /* empty */ 219 220void pred_decl_items() : 221{} 222{ 223 ( pred_decl_item() <SC> )* 224} 225 226// var_decl_items : var_decl_items var_decl_item ';' 227// | /* empty */ 228 229void var_decl_items() #VarDeclItems: 230{} 231{ 232 ( var_decl_item() <SC> )* 233 { //jjtThis.dump(""); 234 // jjtThis.removeChildren(); 235 dict.setNumberOfAllVariables(cg.numberBooleanVariables, cg.numberSetVariables, cg.numberFloatVariables); 236 } 237// { System.out.println(dict); } 238} 239 240// constraint_items: constraint_items constraint_item ';' 241// | /* empty */ 242 243void constraint_items() #ConstraintItems: 244{} 245{ 246 ( constraint_item() <SC> )* 247 { //jjtThis.dump(""); 248 249 // cc.poseDelayedConstraints(); 250 251 // jjtThis.removeChildren(); 252 } 253} 254 255// model_end : solve_item ';' 256// | solve_item ';' output_item ';' 257 258void model_end() #ModelEnd: 259{} 260{ 261 solve_item() <SC> 262 [ output_item() <SC> ] 263} 264 265 266//--------------------------------------------------------------------------- 267// Items 268//--------------------------------------------------------------------------- 269 270// pred_decl_item: 271// PREDICATE IDENT '(' pred_decl_args ')' 272 273void pred_decl_item() : 274{} 275{ 276 <PREDICATE> <IDENT> <LP> pred_decl_args() <RP> 277} 278 279 280// var_decl_item: 281// VAR non_array_ti_expr_tail ':' ident_anns var_decl_item2 282// | non_array_ti_expr_tail ':' ident_anns '=' non_array_flat_expr 283// | ARRAY '[' INT_LITERAL DOTDOT INT_LITERAL ']' OF array_decl_tail 284 285void var_decl_item() #VarDeclItem: 286{ 287 Token t, t1, t2; 288 //kind -- 0=var, 1=non-var; 2=array-var, 3=array-non-var 289} 290{ 291 <VAR> non_array_ti_expr_tail() <COLON> t=ident_anns() [ <ASGN> non_array_flat_expr() ] //var_decl_item2() 292 { 293 jjtThis.setKind(0); jjtThis.setId(t.image); 294 cg.generateVariables(jjtThis, dict, store); 295 // jjtThis.removeChildren(); 296 } 297 298 | non_array_ti_expr_tail() <COLON> t=ident_anns() <ASGN> non_array_flat_expr() 299 { jjtThis.setKind(1); 300 jjtThis.setId(t.image); 301 cg.generateParameters(jjtThis, dict); 302 // jjtThis.removeChildren(); 303 } 304 305 | <ARRAY> <LBOX> t1=<INT_LITERAL> <DOTDOT> t2=<INT_LITERAL> <RBOX> <OF> array_decl_tail(jjtThis) 306 { jjtThis.setIndexes(Integer.parseInt(t1.image), Integer.parseInt(t2.image)); 307 cg.generateArray(jjtThis, dict, store); 308 // jjtThis.removeChildren(); 309 } 310} 311 312// var_decl_item2: 313// '=' non_array_flat_expr 314// | /*empty*/ 315 316// void var_decl_item2() : 317// {} 318// { 319// [ <ASGN> non_array_flat_expr() ] 320// } 321 322// array_decl_tail: 323// non_array_ti_expr_tail ':' ident_anns '=' array_literal 324// | VAR non_array_ti_expr_tail ':' ident_anns array_decl_tail2 325 326void array_decl_tail(ASTVarDeclItem v) : 327{Token t;} 328{ 329 ( 330 non_array_ti_expr_tail() <COLON> t=ident_anns() <ASGN> array_literal() 331 {v.setKind(3); 332 } 333 | <VAR> non_array_ti_expr_tail() <COLON> t=ident_anns() [ <ASGN> array_literal() ] //array_decl_tail2() 334 {v.setKind(2); } 335 ) 336 337 {v.setId(t.image);} 338} 339 340// array_decl_tail2: 341// '=' array_literal 342// | /*empty*/ 343 344// void array_decl_tail2() : 345// {} 346// { 347// [ <ASGN> array_literal() ] 348// } 349 350// ident_anns: 351// IDENT annotations 352 353Token ident_anns() : 354{Token t;} 355{ 356 t=<IDENT> annotations() 357 358 {return t;} 359} 360 361// constraint_item: 362// CONSTRAINT constraint_elem annotations 363 364void constraint_item() #Constraint: 365{} 366{ 367 <CONSTRAINT> constraint_elem() annotations() 368 { // jjtThis.dump(""); 369 cc.generateAlias(jjtThis); 370 // jjtThis.removeChildren(); 371 } 372} 373 374// constraint_elem: 375// IDENT '(' flat_exprs ')' 376// | variable_expr 377 378void constraint_elem() #ConstElem: 379{Token t;} 380{ 381// ( 382// LOOKAHEAD(2) 383 t =<IDENT> <LP> flat_exprs() <RP> 384 {jjtThis.setName(t.image); 385 } 386 // new flatzinc does not support variable as constraint any longer 387 // can be deleted 388// | variable_expr() 389// { 390// cc.generateVarConstraint(jjtThis, dict); 391// jjtThis.removeChildren(); 392// } 393// ) 394 395} 396 397// solve_item: 398// SOLVE annotations solve_kind 399 400void solve_item() #SolveItem: 401{} 402{ 403 <SOLVE> annotations() solve_kind() 404 { 405 // solver.search(jjtThis, dict, options); 406 } 407} 408 409// solve_kind: 410// SATISFY 411// | MINIMIZE solve_expr 412// | MAXIMIZE solve_expr 413 414void solve_kind() #SolveKind: 415{Token t;} 416{ 417 ( t=<SATISFY> 418 | t=<MINIMIZE> solve_expr() 419 | t=<MAXIMIZE> solve_expr() 420 ) 421 422 {jjtThis.setKind(t.image);} 423} 424 425// output_item: 426// OUTPUT '[' output_elems ']' 427 428void output_item() : 429{} 430{ 431 <OUTPUT> <LBOX> output_elems() <RBOX> 432} 433 434// output_elems: 435// output_elem ',' output_elems 436// | output_elem 437 438void output_elems() : 439{} 440{ 441 output_elem() ( <COMMA> output_elem() )* 442} 443 444// output_elem: 445// SHOW '(' flat_expr ')' 446// | SHOW_COND '(' flat_expr ',' flat_expr ',' flat_expr ')' 447// | STRING_LITERAL 448 449void output_elem() : 450{} 451{ 452 <SHOW> <LP> flat_expr() <RP> 453 | <SHOW_COND> <LP> flat_expr() <COMMA> flat_expr() <COMMA> flat_expr() <RP> 454 | <STRING_LITERAL> 455} 456 457//--------------------------------------------------------------------------- 458// Predicate parameters 459//--------------------------------------------------------------------------- 460 461// pred_decl_args: 462// pred_decl_arg "," pred_decl_args 463// | pred_decl_arg 464 465void pred_decl_args() : 466{} 467{ 468 pred_decl_arg() ( <COMMA> pred_decl_arg() )* 469} 470 471// pred_decl_arg: 472// non_array_ti_expr_tail ':' IDENT 473// | VAR non_array_ti_expr_tail ':' IDENT 474// | ARRAY '[' pred_arg_array_index ']' OF pred_arg_array_tail ':' IDENT 475 476void pred_decl_arg() : 477{} 478{ 479 non_array_ti_expr_tail() <COLON> <IDENT> 480 | <VAR> non_array_ti_expr_tail() <COLON> <IDENT> 481 | <ARRAY> <LBOX> pred_arg_array_index() (<COMMA> pred_arg_array_index())* <RBOX> <OF> pred_arg_array_tail() <COLON> <IDENT> 482} 483 484// pred_arg_array_index: 485// INT 486// | INT_LITERAL DOTDOT INT_LITERAL 487 488void pred_arg_array_index() : 489{} 490{ 491 <INT> | <INT_LITERAL> <DOTDOT> <INT_LITERAL> 492 493} 494 495// pred_arg_array_tail: 496// non_array_ti_expr_tail 497// | VAR non_array_ti_expr_tail 498 499void pred_arg_array_tail() : 500{} 501{ 502 non_array_ti_expr_tail() 503 | <VAR> non_array_ti_expr_tail() 504} 505 506//--------------------------------------------------------------------------- 507// Type-Inst Expression Tails 508//--------------------------------------------------------------------------- 509 510// non_array_ti_expr_tail: 511// scalar_ti_expr_tail 512// | set_ti_expr_tail 513 514void non_array_ti_expr_tail() : 515{} 516{ 517 scalar_ti_expr_tail() 518 | set_ti_expr_tail() 519} 520 521// scalar_ti_expr_tail: 522// bool_ti_expr_tail 523// | int_ti_expr_tail 524// | float_ti_expr_tail 525 526void scalar_ti_expr_tail() : 527{} 528{ 529 ( 530 bool_ti_expr_tail() 531 | int_ti_expr_tail() 532 | float_ti_expr_tail() 533 ) 534} 535 536// bool_ti_expr_tail: 537// BOOL 538 539void bool_ti_expr_tail() #BoolTiExprTail: 540{} 541{ 542 <BOOL> 543} 544 545// int_ti_expr_tail: 546// INT 547// | INT_LITERAL DOTDOT INT_LITERAL 548// | '{' int_literals '}' 549 550void int_ti_expr_tail() #IntTiExprTail: 551{//type 0=int; 1=interval; 2=list; 552 Token t1, t2; 553} 554{ 555 <INT> {jjtThis.setType(0);} 556 | t1=<INT_LITERAL> <DOTDOT> t2=<INT_LITERAL> 557 { 558 jjtThis.setType(1); 559 jjtThis.setLowHigh(Integer.parseInt(t1.image), Integer.parseInt(t2.image)); 560 } 561 | <LB> int_literals() <RB> 562 {jjtThis.setType(2);} 563} 564 565// float_ti_expr_tail: 566// FLOAT 567// | FLOAT_LITERAL DOTDOT FLOAT_LITERAL 568 569void float_ti_expr_tail() #FloatTiExprTail: 570{//type 0=int; 1=interval; 571 Token t1, t2; 572} 573{ 574 ( 575 <FLOAT> {jjtThis.setType(0);} 576 | t1=<FLOAT_LITERAL> <DOTDOT> t2=<FLOAT_LITERAL> 577 { 578 jjtThis.setType(1); 579 jjtThis.setLowHigh(Double.parseDouble(t1.image), Double.parseDouble(t2.image)); 580 } 581 ) 582 // { System.err.println("Float not supported; compilation aborted."); System.exit(0); } 583} 584 585// set_ti_expr_tail: 586// SET OF scalar_ti_expr_tail 587 588void set_ti_expr_tail() #SetTiExprTail: 589{} 590{ 591 <SET> <OF> scalar_ti_expr_tail() 592} 593 594//--------------------------------------------------------------------------- 595// Expressions 596//--------------------------------------------------------------------------- 597 598// ann_exprs: 599// ann_expr ',' ann_exprs 600// | ann_expr 601 602void ann_exprs() : 603{} 604{ 605 ann_expr() ( <COMMA> ann_expr() )* 606} 607 608// ann_expr: 609// IDENT '(' ann_exprs ')' 610// | flat_expr 611 612void ann_expr() #AnnExpr: 613{Token t;} 614{ 615 616 LOOKAHEAD(2) 617 t = <IDENT> <LP> ann_exprs() <RP> 618 { jjtThis.setIdent(t.image); } 619| flat_expr() 620 621} 622 623// flat_exprs: 624// flat_expr ',' flat_exprs 625// | flat_expr 626 627void flat_exprs() : 628{} 629{ 630 flat_expr() (<COMMA> flat_expr())* 631} 632 633// flat_expr: 634// non_array_flat_expr 635// | array_literal 636 637void flat_expr() : 638{} 639{ 640 non_array_flat_expr() 641 | array_literal() 642} 643 644// non_array_flat_exprs: 645// non_array_flat_expr ',' non_array_flat_exprs 646// | non_array_flat_expr 647 648void non_array_flat_exprs() : 649{} 650{ 651 non_array_flat_expr() ( <COMMA> non_array_flat_expr() )* 652} 653 654// non_array_flat_expr: 655// scalar_flat_expr 656// | set_literal 657 658void non_array_flat_expr() : 659{} 660{ 661// LOOKAHEAD(set_literal()) 662 LOOKAHEAD(3) 663 set_literal() 664 | scalar_flat_expr() 665} 666 667// scalar_flat_exprs: 668// scalar_flat_expr ',' scalar_flat_exprs 669// | scalar_flat_expr 670 671void scalar_flat_exprs() : 672{} 673{ 674 scalar_flat_expr() ( <COMMA> scalar_flat_expr())* 675} 676 677// scalar_flat_expr: 678// IDENT 679// | array_access_expr 680// | bool_literal 681// | INT_LITERAL 682// | FLOAT_LITERAL 683// | STRING_LITERAL 684 685void scalar_flat_expr() #ScalarFlatExpr: 686{Token t; 687 // type = 0-int; 1=bool; 2=ident; 3= array_access; 4=string; 5=float; 688 ArrayAccess aa; 689} 690{ 691// LOOKAHEAD(array_access_expr()) 692 LOOKAHEAD(2) 693 aa = array_access_expr() 694 { jjtThis.setType(3); 695 jjtThis.setIdent(aa.getIdent()); 696 jjtThis.setInt(aa.getIndex()); 697 } 698 | t = <IDENT> 699 { jjtThis.setType(2); jjtThis.setIdent(t.image); } 700 | t = bool_literal() 701 { jjtThis.setType(1); 702 int val = Boolean.parseBoolean(t.image)==true?1:0; 703 jjtThis.setInt(val); 704 } 705 | t = <INT_LITERAL> { jjtThis.setType(0); jjtThis.setInt(Integer.parseInt(t.image)); } 706 | t = <FLOAT_LITERAL> { jjtThis.setType(5); jjtThis.setFloat(Double.parseDouble(t.image));} 707 | t = <STRING_LITERAL> { jjtThis.setType(4); } 708} 709 710// int_flat_expr: 711// IDENT 712// | array_access_expr 713// | INT_LITERAL 714 715void int_flat_expr() #IntFlatExpr: 716{ Token t; 717 ArrayAccess aa; 718} 719{ 720 LOOKAHEAD(2) 721 <IDENT> // look-up 722 | aa = array_access_expr() //look-up 723 { int[] intArray = dict.getIntArray(aa.getIdent()); 724 if (intArray != null) { 725 int value = intArray[aa.getIndex() - 1]; 726 jjtThis.setInt(value); 727 } 728 else 729 System.err.println("Cannot find value for "+aa); System.exit(0); 730 } 731 | t=<INT_LITERAL> {jjtThis.setInt(Integer.parseInt(t.image));} 732} 733 734// variable_expr: 735// IDENT 736// | array_access_expr 737 738void variable_expr() #VariableExpr: 739{ Token t; 740 ArrayAccess aa=null; 741// String ident=null; 742} 743{ 744 LOOKAHEAD(2) 745 aa = array_access_expr() {jjtThis.setArrayAccess(aa); } 746 | t=<IDENT> {jjtThis.setIdent(t.image);} 747} 748 749// solve_expr: 750// IDENT 751// | array_access_expr 752// | IDENT '(' flat_exprs ')' 753 754void solve_expr() #SolveExpr: 755{ Token t; 756 ArrayAccess aa; 757} 758{ 759 LOOKAHEAD(2) 760 aa = array_access_expr() 761 {jjtThis.setType(1); jjtThis.setIdent(aa.getIdent()); jjtThis.setIndex(aa.getIndex()); } 762 | LOOKAHEAD(2) <IDENT> <LP> flat_exprs() <RP> 763 | t = <IDENT> 764 {jjtThis.setType(0); jjtThis.setIdent(t.image); } 765} 766 767// array_access_expr: 768// IDENT '[' int_index_expr ']' 769 770ArrayAccess array_access_expr() : 771{Token t; 772 String ident; 773 int index;} 774{ 775 t=<IDENT> <LBOX> index=int_index_expr() <RBOX> 776 { ident = t.image; } 777 { return new ArrayAccess(ident, index); } 778} 779 780// int_index_expr: 781// IDENT 782// | INT_LITERAL 783 784int int_index_expr() : 785{ Token t; 786 int i=-1; 787} 788{ 789 t=<IDENT> // need to make a look-up in a dictionary 790 { String ident = t.image; 791 i = dict.getInt(ident); 792 return i; 793 } 794 | 795 ( t=<INT_LITERAL> {i = Integer.parseInt(t.image) - 1; /* -1 since java starts arrays from 0 not 1 */}) 796 797// {System.out.println("index = " + i);} 798 {return i;} 799} 800 801// bool_literal: 802// FALSE 803// | TRUE 804 805Token bool_literal() : 806{Token t;} 807{ 808 ( 809 t=<FALSE> | t=<TRUE> 810 ) 811 {return t;} 812} 813 814// int_literals: 815// INT_LITERAL ',' int_literals 816// | INT_LITERAL 817 818void int_literals() #IntLiterals: 819{ 820Token t; 821ArrayList<Integer> l = new ArrayList<Integer>(); 822} 823 824{ 825 ( 826 t=<INT_LITERAL> {l.add(Integer.parseInt(t.image)); } 827 ( <COMMA> t=<INT_LITERAL> {l.add(Integer.parseInt(t.image));})* 828 ) 829 830 {jjtThis.setList(l);} 831} 832 833// set_literal: 834// '{' scalar_flat_exprs '}' 835// | '{' '}' 836// | int_flat_expr DOTDOT int_flat_expr 837 838void set_literal() #SetLiteral: 839{} 840{ 841 842 ( <LB> [ scalar_flat_exprs() ] <RB> 843 {jjtThis.setType(1);} 844 ) 845 | (int_flat_expr() <DOTDOT> int_flat_expr() 846 {jjtThis.setType(0);} 847 ) 848} 849 850// array_literal: 851// '[' non_array_flat_exprs ']' 852// | '[' ']' 853 854void array_literal() #ArrayLiteral: 855{} 856{ 857 <LBOX> [ non_array_flat_exprs() ] <RBOX> 858} 859 860//--------------------------------------------------------------------------- 861// Annotations 862//--------------------------------------------------------------------------- 863 864// annotations: 865// COLONCOLON annotation annotations 866// | /* empty */ 867 868void annotations() : 869{} 870{ 871 ( <COLONCOLON> annotation() )* 872} 873 874// annotation: 875// IDENT '(' ann_exprs ')' 876// | IDENT 877 878void annotation() #Annotation: 879{Token t;} 880{ 881 LOOKAHEAD(5) 882 t=<IDENT> <LP> annotation() (<COMMA> annotation() )* <RP> 883 {jjtThis.setId(t.image); } 884 | 885 LOOKAHEAD(2) // addition to accept seq_search and priority_search 886 <LBOX> annotation() (<COMMA> annotation() )* <RBOX> 887 {jjtThis.setId("$vector"); } 888 | 889 ann_expr() 890 {jjtThis.setId("$expr"); } 891} 892