1 %token _BANG_t 2 %token _BANG_EQUALS_t 3 %token _AMPER_t 4 %token _AMPERAMPER_t 5 %token _LPAREN_t 6 %token _RPAREN_t 7 %token _PLUS_EQUALS_t 8 %token _COLON_t 9 %token _SEMIC_t 10 %token _LANGLE_t 11 %token _LANGLE_EQUALS_t 12 %token _EQUALS_t 13 %token _RANGLE_t 14 %token _RANGLE_EQUALS_t 15 %token _QUESTION_EQUALS_t 16 %token _LBRACKET_t 17 %token _RBRACKET_t 18 %token ACTIONS_t 19 %token BIND_t 20 %token BREAK_t 21 %token CASE_t 22 %token CLASS_t 23 %token CONTINUE_t 24 %token DEFAULT_t 25 %token ELSE_t 26 %token EXISTING_t 27 %token FOR_t 28 %token IF_t 29 %token IGNORE_t 30 %token IN_t 31 %token INCLUDE_t 32 %token LOCAL_t 33 %token MODULE_t 34 %token ON_t 35 %token PIECEMEAL_t 36 %token QUIETLY_t 37 %token RETURN_t 38 %token RULE_t 39 %token SWITCH_t 40 %token TOGETHER_t 41 %token UPDATED_t 42 %token WHILE_t 43 %token _LBRACE_t 44 %token _BAR_t 45 %token _BARBAR_t 46 %token _RBRACE_t 47 /* 48 * Copyright 1993, 2000 Christopher Seiwald. 49 * 50 * This file is part of Jam - see jam.c for Copyright information. 51 */ 52 53 /* This file is ALSO: 54 * Copyright 2001-2004 David Abrahams. 55 * Distributed under the Boost Software License, Version 1.0. 56 * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) 57 */ 58 59 /* 60 * jamgram.yy - jam grammar 61 * 62 * 04/13/94 (seiwald) - added shorthand L0 for null list pointer 63 * 06/01/94 (seiwald) - new 'actions existing' does existing sources 64 * 08/23/94 (seiwald) - Support for '+=' (append to variable) 65 * 08/31/94 (seiwald) - Allow ?= as alias for "default =". 66 * 09/15/94 (seiwald) - if conditionals take only single arguments, so 67 * that 'if foo == bar' gives syntax error (use =). 68 * 02/11/95 (seiwald) - when scanning arguments to rules, only treat 69 * punctuation keywords as keywords. All arg lists 70 * are terminated with punctuation keywords. 71 * 72 * 09/11/00 (seiwald) - Support for function calls: 73 * 74 * Rules now return lists (LIST *), rather than void. 75 * 76 * New "[ rule ]" syntax evals rule into a LIST. 77 * 78 * Lists are now generated by compile_list() and 79 * compile_append(), and any other rule that indirectly 80 * makes a list, rather than being built directly here, 81 * so that lists values can contain rule evaluations. 82 * 83 * New 'return' rule sets the return value, though 84 * other statements also may have return values. 85 * 86 * 'run' production split from 'block' production so 87 * that empty blocks can be handled separately. 88 */ 89 90 %token ARG STRING 91 92 %left _BARBAR_t _BAR_t 93 %left _AMPERAMPER_t _AMPER_t 94 %left _EQUALS_t _BANG_EQUALS_t IN_t 95 %left _LANGLE_t _LANGLE_EQUALS_t _RANGLE_t _RANGLE_EQUALS_t 96 %left _BANG_t 97 98 %{ 99 #include "jam.h" 100 101 #include "lists.h" 102 #include "parse.h" 103 #include "scan.h" 104 #include "compile.h" 105 #include "object.h" 106 #include "rules.h" 107 108 # define YYINITDEPTH 5000 /* for C++ parsing */ 109 # define YYMAXDEPTH 10000 /* for OSF and other less endowed yaccs */ 110 111 # define F0 -1 112 # define P0 (PARSE *)0 113 # define S0 (OBJECT *)0 114 115 # define pappend( l,r ) parse_make( PARSE_APPEND,l,r,P0,S0,S0,0 ) 116 # define peval( c,l,r ) parse_make( PARSE_EVAL,l,r,P0,S0,S0,c ) 117 # define pfor( s,l,r,x ) parse_make( PARSE_FOREACH,l,r,P0,s,S0,x ) 118 # define pif( l,r,t ) parse_make( PARSE_IF,l,r,t,S0,S0,0 ) 119 # define pincl( l ) parse_make( PARSE_INCLUDE,l,P0,P0,S0,S0,0 ) 120 # define plist( s ) parse_make( PARSE_LIST,P0,P0,P0,s,S0,0 ) 121 # define plocal( l,r,t ) parse_make( PARSE_LOCAL,l,r,t,S0,S0,0 ) 122 # define pmodule( l,r ) parse_make( PARSE_MODULE,l,r,P0,S0,S0,0 ) 123 # define pclass( l,r ) parse_make( PARSE_CLASS,l,r,P0,S0,S0,0 ) 124 # define pnull() parse_make( PARSE_NULL,P0,P0,P0,S0,S0,0 ) 125 # define pon( l,r ) parse_make( PARSE_ON,l,r,P0,S0,S0,0 ) 126 # define prule( s,p ) parse_make( PARSE_RULE,p,P0,P0,s,S0,0 ) 127 # define prules( l,r ) parse_make( PARSE_RULES,l,r,P0,S0,S0,0 ) 128 # define pset( l,r,a ) parse_make( PARSE_SET,l,r,P0,S0,S0,a ) 129 # define pset1( l,r,t,a ) parse_make( PARSE_SETTINGS,l,r,t,S0,S0,a ) 130 # define psetc( s,p,a,l ) parse_make( PARSE_SETCOMP,p,a,P0,s,S0,l ) 131 # define psete( s,l,s1,f ) parse_make( PARSE_SETEXEC,l,P0,P0,s,s1,f ) 132 # define pswitch( l,r ) parse_make( PARSE_SWITCH,l,r,P0,S0,S0,0 ) 133 # define pwhile( l,r ) parse_make( PARSE_WHILE,l,r,P0,S0,S0,0 ) 134 # define preturn( l ) parse_make( PARSE_RETURN,l,P0,P0,S0,S0,0 ) 135 # define pbreak() parse_make( PARSE_BREAK,P0,P0,P0,S0,S0,0 ) 136 # define pcontinue() parse_make( PARSE_CONTINUE,P0,P0,P0,S0,S0,0 ) 137 138 # define pnode( l,r ) parse_make( F0,l,r,P0,S0,S0,0 ) 139 # define psnode( s,l ) parse_make( F0,l,P0,P0,s,S0,0 ) 140 141 %} 142 143 %% 144 145 run : /* empty */ 146 /* do nothing */ 147 | rules 148 { parse_save( $1.parse ); } 149 ; 150 151 /* 152 * block - zero or more rules 153 * rules - one or more rules 154 * rule - any one of jam's rules 155 * right-recursive so rules execute in order. 156 */ 157 158 block : null 159 { $$.parse = $1.parse; } 160 | rules 161 { $$.parse = $1.parse; } 162 ; 163 164 rules : rule 165 { $$.parse = $1.parse; } 166 | rule rules 167 { $$.parse = prules( $1.parse, $2.parse ); } 168 | LOCAL_t { yymode( SCAN_ASSIGN ); } list assign_list_opt _SEMIC_t { yymode( SCAN_NORMAL ); } block 169 { $$.parse = plocal( $3.parse, $4.parse, $7.parse ); } 170 ; 171 172 null : /* empty */ 173 { $$.parse = pnull(); } 174 ; 175 176 assign_list_opt : _EQUALS_t { yymode( SCAN_PUNCT ); } list 177 { $$.parse = $3.parse; $$.number = ASSIGN_SET; } 178 | null 179 { $$.parse = $1.parse; $$.number = ASSIGN_APPEND; } 180 ; 181 182 arglist_opt : _LPAREN_t lol _RPAREN_t 183 { $$.parse = $2.parse; } 184 | 185 { $$.parse = P0; } 186 ; 187 188 local_opt : LOCAL_t 189 { $$.number = 1; } 190 | /* empty */ 191 { $$.number = 0; } 192 ; 193 194 else_opt : ELSE_t rule 195 { $$.parse = $2.parse; } 196 | /* empty */ 197 { $$.parse = pnull(); } 198 199 rule : _LBRACE_t block _RBRACE_t 200 { $$.parse = $2.parse; } 201 | INCLUDE_t { yymode( SCAN_PUNCT ); } list _SEMIC_t 202 { $$.parse = pincl( $3.parse ); yymode( SCAN_NORMAL ); } 203 | ARG { yymode( SCAN_PUNCT ); } lol _SEMIC_t 204 { $$.parse = prule( $1.string, $3.parse ); yymode( SCAN_NORMAL ); } 205 | arg assign { yymode( SCAN_PUNCT ); } list _SEMIC_t 206 { $$.parse = pset( $1.parse, $4.parse, $2.number ); yymode( SCAN_NORMAL ); } 207 | arg ON_t { yymode( SCAN_ASSIGN ); } list assign { yymode( SCAN_PUNCT ); } list _SEMIC_t 208 { $$.parse = pset1( $1.parse, $4.parse, $7.parse, $5.number ); yymode( SCAN_NORMAL ); } 209 | RETURN_t { yymode( SCAN_PUNCT ); } list _SEMIC_t 210 { $$.parse = preturn( $3.parse ); yymode( SCAN_NORMAL ); } 211 | BREAK_t _SEMIC_t 212 { $$.parse = pbreak(); } 213 | CONTINUE_t _SEMIC_t 214 { $$.parse = pcontinue(); } 215 | FOR_t local_opt ARG IN_t { yymode( SCAN_PUNCT ); } list _LBRACE_t { yymode( SCAN_NORMAL ); } block _RBRACE_t 216 { $$.parse = pfor( $3.string, $6.parse, $9.parse, $2.number ); } 217 | SWITCH_t { yymode( SCAN_PUNCT ); } list _LBRACE_t { yymode( SCAN_NORMAL ); } cases _RBRACE_t 218 { $$.parse = pswitch( $3.parse, $6.parse ); } 219 | IF_t { yymode( SCAN_CONDB ); } expr _LBRACE_t { yymode( SCAN_NORMAL ); } block _RBRACE_t else_opt 220 { $$.parse = pif( $3.parse, $6.parse, $8.parse ); } 221 | MODULE_t { yymode( SCAN_PUNCT ); } list _LBRACE_t { yymode( SCAN_NORMAL ); } block _RBRACE_t 222 { $$.parse = pmodule( $3.parse, $6.parse ); } 223 | CLASS_t { yymode( SCAN_PUNCT ); } lol _LBRACE_t { yymode( SCAN_NORMAL ); } block _RBRACE_t 224 { $$.parse = pclass( $3.parse, $6.parse ); } 225 | WHILE_t { yymode( SCAN_CONDB ); } expr { yymode( SCAN_NORMAL ); } _LBRACE_t block _RBRACE_t 226 { $$.parse = pwhile( $3.parse, $6.parse ); } 227 | local_opt RULE_t { yymode( SCAN_PUNCT ); } ARG { yymode( SCAN_PARAMS ); } arglist_opt { yymode( SCAN_NORMAL ); } rule 228 { $$.parse = psetc( $4.string, $8.parse, $6.parse, $1.number ); } 229 | ON_t arg rule 230 { $$.parse = pon( $2.parse, $3.parse ); } 231 | ACTIONS_t eflags ARG bindlist _LBRACE_t 232 { yymode( SCAN_STRING ); } 233 STRING 234 { yymode( SCAN_NORMAL ); } 235 _RBRACE_t 236 { $$.parse = psete( $3.string,$4.parse,$7.string,$2.number ); } 237 ; 238 239 /* 240 * assign - = or += 241 */ 242 243 assign : _EQUALS_t 244 { $$.number = ASSIGN_SET; } 245 | _PLUS_EQUALS_t 246 { $$.number = ASSIGN_APPEND; } 247 | _QUESTION_EQUALS_t 248 { $$.number = ASSIGN_DEFAULT; } 249 | DEFAULT_t _EQUALS_t 250 { $$.number = ASSIGN_DEFAULT; } 251 ; 252 253 /* 254 * expr - an expression for if 255 */ 256 expr : arg 257 { $$.parse = peval( EXPR_EXISTS, $1.parse, pnull() ); yymode( SCAN_COND ); } 258 | expr _EQUALS_t { yymode( SCAN_CONDB ); } expr 259 { $$.parse = peval( EXPR_EQUALS, $1.parse, $4.parse ); } 260 | expr _BANG_EQUALS_t { yymode( SCAN_CONDB ); } expr 261 { $$.parse = peval( EXPR_NOTEQ, $1.parse, $4.parse ); } 262 | expr _LANGLE_t { yymode( SCAN_CONDB ); } expr 263 { $$.parse = peval( EXPR_LESS, $1.parse, $4.parse ); } 264 | expr _LANGLE_EQUALS_t { yymode( SCAN_CONDB ); } expr 265 { $$.parse = peval( EXPR_LESSEQ, $1.parse, $4.parse ); } 266 | expr _RANGLE_t { yymode( SCAN_CONDB ); } expr 267 { $$.parse = peval( EXPR_MORE, $1.parse, $4.parse ); } 268 | expr _RANGLE_EQUALS_t { yymode( SCAN_CONDB ); } expr 269 { $$.parse = peval( EXPR_MOREEQ, $1.parse, $4.parse ); } 270 | expr _AMPER_t { yymode( SCAN_CONDB ); } expr 271 { $$.parse = peval( EXPR_AND, $1.parse, $4.parse ); } 272 | expr _AMPERAMPER_t { yymode( SCAN_CONDB ); } expr 273 { $$.parse = peval( EXPR_AND, $1.parse, $4.parse ); } 274 | expr _BAR_t { yymode( SCAN_CONDB ); } expr 275 { $$.parse = peval( EXPR_OR, $1.parse, $4.parse ); } 276 | expr _BARBAR_t { yymode( SCAN_CONDB ); } expr 277 { $$.parse = peval( EXPR_OR, $1.parse, $4.parse ); } 278 | arg IN_t { yymode( SCAN_PUNCT ); } list 279 { $$.parse = peval( EXPR_IN, $1.parse, $4.parse ); yymode( SCAN_COND ); } 280 | _BANG_t { yymode( SCAN_CONDB ); } expr 281 { $$.parse = peval( EXPR_NOT, $3.parse, pnull() ); } 282 | _LPAREN_t { yymode( SCAN_CONDB ); } expr _RPAREN_t 283 { $$.parse = $3.parse; } 284 ; 285 286 287 /* 288 * cases - action elements inside a 'switch' 289 * case - a single action element inside a 'switch' 290 * right-recursive rule so cases can be examined in order. 291 */ 292 293 cases : /* empty */ 294 { $$.parse = P0; } 295 | case cases 296 { $$.parse = pnode( $1.parse, $2.parse ); } 297 ; 298 299 case : CASE_t { yymode( SCAN_CASE ); } ARG _COLON_t { yymode( SCAN_NORMAL ); } block 300 { $$.parse = psnode( $3.string, $6.parse ); } 301 ; 302 303 /* 304 * lol - list of lists 305 * right-recursive rule so that lists can be added in order. 306 */ 307 308 lol : list 309 { $$.parse = pnode( P0, $1.parse ); } 310 | list _COLON_t lol 311 { $$.parse = pnode( $3.parse, $1.parse ); } 312 ; 313 314 /* 315 * list - zero or more args in a LIST 316 * listp - list (in puncutation only mode) 317 * arg - one ARG or function call 318 */ 319 320 list : listp 321 { $$.parse = $1.parse; } 322 ; 323 324 listp : /* empty */ 325 { $$.parse = pnull(); } 326 | listp arg 327 { $$.parse = pappend( $1.parse, $2.parse ); } 328 ; 329 330 arg : ARG 331 { $$.parse = plist( $1.string ); } 332 | _LBRACKET_t { $$.number = yymode( SCAN_CALL ); } func _RBRACKET_t 333 { $$.parse = $3.parse; yymode( $2.number ); } 334 ; 335 336 /* 337 * func - a function call (inside []) 338 * This needs to be split cleanly out of 'rule' 339 */ 340 341 func : ARG { yymode( SCAN_PUNCT ); } lol 342 { $$.parse = prule( $1.string, $3.parse ); } 343 | ON_t arg ARG { yymode( SCAN_PUNCT ); } lol 344 { $$.parse = pon( $2.parse, prule( $3.string, $5.parse ) ); } 345 | ON_t arg RETURN_t { yymode( SCAN_PUNCT ); } list 346 { $$.parse = pon( $2.parse, $5.parse ); } 347 ; 348 349 350 /* 351 * eflags - zero or more modifiers to 'executes' 352 * eflag - a single modifier to 'executes' 353 */ 354 355 eflags : /* empty */ 356 { $$.number = 0; } 357 | eflags eflag 358 { $$.number = $1.number | $2.number; } 359 ; 360 361 eflag : UPDATED_t 362 { $$.number = EXEC_UPDATED; } 363 | TOGETHER_t 364 { $$.number = EXEC_TOGETHER; } 365 | IGNORE_t 366 { $$.number = EXEC_IGNORE; } 367 | QUIETLY_t 368 { $$.number = EXEC_QUIETLY; } 369 | PIECEMEAL_t 370 { $$.number = EXEC_PIECEMEAL; } 371 | EXISTING_t 372 { $$.number = EXEC_EXISTING; } 373 ; 374 375 376 /* 377 * bindlist - list of variable to bind for an action 378 */ 379 380 bindlist : /* empty */ 381 { $$.parse = pnull(); } 382 | BIND_t { yymode( SCAN_PUNCT ); } list 383 { $$.parse = $3.parse; } 384 ; 385 386 387