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 YYMAXDEPTH 10000 /* for OSF and other less endowed yaccs */ 109 110 # define F0 -1 111 # define P0 (PARSE *)0 112 # define S0 (OBJECT *)0 113 114 # define pappend( l,r ) parse_make( PARSE_APPEND,l,r,P0,S0,S0,0 ) 115 # define peval( c,l,r ) parse_make( PARSE_EVAL,l,r,P0,S0,S0,c ) 116 # define pfor( s,l,r,x ) parse_make( PARSE_FOREACH,l,r,P0,s,S0,x ) 117 # define pif( l,r,t ) parse_make( PARSE_IF,l,r,t,S0,S0,0 ) 118 # define pincl( l ) parse_make( PARSE_INCLUDE,l,P0,P0,S0,S0,0 ) 119 # define plist( s ) parse_make( PARSE_LIST,P0,P0,P0,s,S0,0 ) 120 # define plocal( l,r,t ) parse_make( PARSE_LOCAL,l,r,t,S0,S0,0 ) 121 # define pmodule( l,r ) parse_make( PARSE_MODULE,l,r,P0,S0,S0,0 ) 122 # define pclass( l,r ) parse_make( PARSE_CLASS,l,r,P0,S0,S0,0 ) 123 # define pnull() parse_make( PARSE_NULL,P0,P0,P0,S0,S0,0 ) 124 # define pon( l,r ) parse_make( PARSE_ON,l,r,P0,S0,S0,0 ) 125 # define prule( s,p ) parse_make( PARSE_RULE,p,P0,P0,s,S0,0 ) 126 # define prules( l,r ) parse_make( PARSE_RULES,l,r,P0,S0,S0,0 ) 127 # define pset( l,r,a ) parse_make( PARSE_SET,l,r,P0,S0,S0,a ) 128 # define pset1( l,r,t,a ) parse_make( PARSE_SETTINGS,l,r,t,S0,S0,a ) 129 # define psetc( s,p,a,l ) parse_make( PARSE_SETCOMP,p,a,P0,s,S0,l ) 130 # define psete( s,l,s1,f ) parse_make( PARSE_SETEXEC,l,P0,P0,s,s1,f ) 131 # define pswitch( l,r ) parse_make( PARSE_SWITCH,l,r,P0,S0,S0,0 ) 132 # define pwhile( l,r ) parse_make( PARSE_WHILE,l,r,P0,S0,S0,0 ) 133 # define preturn( l ) parse_make( PARSE_RETURN,l,P0,P0,S0,S0,0 ) 134 # define pbreak() parse_make( PARSE_BREAK,P0,P0,P0,S0,S0,0 ) 135 # define pcontinue() parse_make( PARSE_CONTINUE,P0,P0,P0,S0,S0,0 ) 136 137 # define pnode( l,r ) parse_make( F0,l,r,P0,S0,S0,0 ) 138 # define psnode( s,l ) parse_make( F0,l,P0,P0,s,S0,0 ) 139 140 %} 141 142 %% 143 144 run : /* empty */ 145 /* do nothing */ 146 | rules 147 { parse_save( $1.parse ); } 148 ; 149 150 /* 151 * block - zero or more rules 152 * rules - one or more rules 153 * rule - any one of jam's rules 154 * right-recursive so rules execute in order. 155 */ 156 157 block : null 158 { $$.parse = $1.parse; } 159 | rules 160 { $$.parse = $1.parse; } 161 ; 162 163 rules : rule 164 { $$.parse = $1.parse; } 165 | rule rules 166 { $$.parse = prules( $1.parse, $2.parse ); } 167 | LOCAL_t list assign_list_opt _SEMIC_t block 168 { $$.parse = plocal( $2.parse, $3.parse, $5.parse ); } 169 ; 170 171 null : /* empty */ 172 { $$.parse = pnull(); } 173 ; 174 175 assign_list_opt : _EQUALS_t list 176 { $$.parse = $2.parse; $$.number = ASSIGN_SET; } 177 | null 178 { $$.parse = $1.parse; $$.number = ASSIGN_APPEND; } 179 ; 180 181 arglist_opt : _LPAREN_t lol _RPAREN_t 182 { $$.parse = $2.parse; } 183 | 184 { $$.parse = P0; } 185 ; 186 187 local_opt : LOCAL_t 188 { $$.number = 1; } 189 | /* empty */ 190 { $$.number = 0; } 191 ; 192 193 rule : _LBRACE_t block _RBRACE_t 194 { $$.parse = $2.parse; } 195 | INCLUDE_t list _SEMIC_t 196 { $$.parse = pincl( $2.parse ); } 197 | ARG lol _SEMIC_t 198 { $$.parse = prule( $1.string, $2.parse ); } 199 | arg assign list _SEMIC_t 200 { $$.parse = pset( $1.parse, $3.parse, $2.number ); } 201 | arg ON_t list assign list _SEMIC_t 202 { $$.parse = pset1( $1.parse, $3.parse, $5.parse, $4.number ); } 203 | RETURN_t list _SEMIC_t 204 { $$.parse = preturn( $2.parse ); } 205 | BREAK_t _SEMIC_t 206 { $$.parse = pbreak(); } 207 | CONTINUE_t _SEMIC_t 208 { $$.parse = pcontinue(); } 209 | FOR_t local_opt ARG IN_t list _LBRACE_t block _RBRACE_t 210 { $$.parse = pfor( $3.string, $5.parse, $7.parse, $2.number ); } 211 | SWITCH_t list _LBRACE_t cases _RBRACE_t 212 { $$.parse = pswitch( $2.parse, $4.parse ); } 213 | IF_t expr _LBRACE_t block _RBRACE_t 214 { $$.parse = pif( $2.parse, $4.parse, pnull() ); } 215 | MODULE_t list _LBRACE_t block _RBRACE_t 216 { $$.parse = pmodule( $2.parse, $4.parse ); } 217 | CLASS_t lol _LBRACE_t block _RBRACE_t 218 { $$.parse = pclass( $2.parse, $4.parse ); } 219 | WHILE_t expr _LBRACE_t block _RBRACE_t 220 { $$.parse = pwhile( $2.parse, $4.parse ); } 221 | IF_t expr _LBRACE_t block _RBRACE_t ELSE_t rule 222 { $$.parse = pif( $2.parse, $4.parse, $7.parse ); } 223 | local_opt RULE_t ARG arglist_opt rule 224 { $$.parse = psetc( $3.string, $5.parse, $4.parse, $1.number ); } 225 | ON_t arg rule 226 { $$.parse = pon( $2.parse, $3.parse ); } 227 | ACTIONS_t eflags ARG bindlist _LBRACE_t 228 { yymode( SCAN_STRING ); } 229 STRING 230 { yymode( SCAN_NORMAL ); } 231 _RBRACE_t 232 { $$.parse = psete( $3.string,$4.parse,$7.string,$2.number ); } 233 ; 234 235 /* 236 * assign - = or += 237 */ 238 239 assign : _EQUALS_t 240 { $$.number = ASSIGN_SET; } 241 | _PLUS_EQUALS_t 242 { $$.number = ASSIGN_APPEND; } 243 | _QUESTION_EQUALS_t 244 { $$.number = ASSIGN_DEFAULT; } 245 | DEFAULT_t _EQUALS_t 246 { $$.number = ASSIGN_DEFAULT; } 247 ; 248 249 /* 250 * expr - an expression for if 251 */ 252 expr : arg 253 { $$.parse = peval( EXPR_EXISTS, $1.parse, pnull() ); } 254 | expr _EQUALS_t expr 255 { $$.parse = peval( EXPR_EQUALS, $1.parse, $3.parse ); } 256 | expr _BANG_EQUALS_t expr 257 { $$.parse = peval( EXPR_NOTEQ, $1.parse, $3.parse ); } 258 | expr _LANGLE_t expr 259 { $$.parse = peval( EXPR_LESS, $1.parse, $3.parse ); } 260 | expr _LANGLE_EQUALS_t expr 261 { $$.parse = peval( EXPR_LESSEQ, $1.parse, $3.parse ); } 262 | expr _RANGLE_t expr 263 { $$.parse = peval( EXPR_MORE, $1.parse, $3.parse ); } 264 | expr _RANGLE_EQUALS_t expr 265 { $$.parse = peval( EXPR_MOREEQ, $1.parse, $3.parse ); } 266 | expr _AMPER_t expr 267 { $$.parse = peval( EXPR_AND, $1.parse, $3.parse ); } 268 | expr _AMPERAMPER_t expr 269 { $$.parse = peval( EXPR_AND, $1.parse, $3.parse ); } 270 | expr _BAR_t expr 271 { $$.parse = peval( EXPR_OR, $1.parse, $3.parse ); } 272 | expr _BARBAR_t expr 273 { $$.parse = peval( EXPR_OR, $1.parse, $3.parse ); } 274 | arg IN_t list 275 { $$.parse = peval( EXPR_IN, $1.parse, $3.parse ); } 276 | _BANG_t expr 277 { $$.parse = peval( EXPR_NOT, $2.parse, pnull() ); } 278 | _LPAREN_t expr _RPAREN_t 279 { $$.parse = $2.parse; } 280 ; 281 282 283 /* 284 * cases - action elements inside a 'switch' 285 * case - a single action element inside a 'switch' 286 * right-recursive rule so cases can be examined in order. 287 */ 288 289 cases : /* empty */ 290 { $$.parse = P0; } 291 | case cases 292 { $$.parse = pnode( $1.parse, $2.parse ); } 293 ; 294 295 case : CASE_t ARG _COLON_t block 296 { $$.parse = psnode( $2.string, $4.parse ); } 297 ; 298 299 /* 300 * lol - list of lists 301 * right-recursive rule so that lists can be added in order. 302 */ 303 304 lol : list 305 { $$.parse = pnode( P0, $1.parse ); } 306 | list _COLON_t lol 307 { $$.parse = pnode( $3.parse, $1.parse ); } 308 ; 309 310 /* 311 * list - zero or more args in a LIST 312 * listp - list (in puncutation only mode) 313 * arg - one ARG or function call 314 */ 315 316 list : listp 317 { $$.parse = $1.parse; yymode( SCAN_NORMAL ); } 318 ; 319 320 listp : /* empty */ 321 { $$.parse = pnull(); yymode( SCAN_PUNCT ); } 322 | listp arg 323 { $$.parse = pappend( $1.parse, $2.parse ); } 324 ; 325 326 arg : ARG 327 { $$.parse = plist( $1.string ); } 328 | _LBRACKET_t { yymode( SCAN_NORMAL ); } func _RBRACKET_t 329 { $$.parse = $3.parse; } 330 ; 331 332 /* 333 * func - a function call (inside []) 334 * This needs to be split cleanly out of 'rule' 335 */ 336 337 func : ARG lol 338 { $$.parse = prule( $1.string, $2.parse ); } 339 | ON_t arg ARG lol 340 { $$.parse = pon( $2.parse, prule( $3.string, $4.parse ) ); } 341 | ON_t arg RETURN_t list 342 { $$.parse = pon( $2.parse, $4.parse ); } 343 ; 344 345 346 /* 347 * eflags - zero or more modifiers to 'executes' 348 * eflag - a single modifier to 'executes' 349 */ 350 351 eflags : /* empty */ 352 { $$.number = 0; } 353 | eflags eflag 354 { $$.number = $1.number | $2.number; } 355 ; 356 357 eflag : UPDATED_t 358 { $$.number = EXEC_UPDATED; } 359 | TOGETHER_t 360 { $$.number = EXEC_TOGETHER; } 361 | IGNORE_t 362 { $$.number = EXEC_IGNORE; } 363 | QUIETLY_t 364 { $$.number = EXEC_QUIETLY; } 365 | PIECEMEAL_t 366 { $$.number = EXEC_PIECEMEAL; } 367 | EXISTING_t 368 { $$.number = EXEC_EXISTING; } 369 ; 370 371 372 /* 373 * bindlist - list of variable to bind for an action 374 */ 375 376 bindlist : /* empty */ 377 { $$.parse = pnull(); } 378 | BIND_t list 379 { $$.parse = $2.parse; } 380 ; 381 382 383