aboutsummaryrefslogtreecommitdiff
path: root/src/build.y
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2009-12-21 18:04:02 +0000
committerMike Buland <eichlan@xagasoft.com>2009-12-21 18:04:02 +0000
commitfb28f6800864176be2ffca29e8e664b641f33170 (patch)
treeba9180ac442939edc4eacbe1fdae93c5a7f87cee /src/build.y
parent51e21a316be6e052251b3dfc7d671061ebd67cee (diff)
downloadbuild-fb28f6800864176be2ffca29e8e664b641f33170.tar.gz
build-fb28f6800864176be2ffca29e8e664b641f33170.tar.bz2
build-fb28f6800864176be2ffca29e8e664b641f33170.tar.xz
build-fb28f6800864176be2ffca29e8e664b641f33170.zip
m3 is copied into trunk, we should be good to go, now.
Diffstat (limited to 'src/build.y')
-rw-r--r--src/build.y741
1 files changed, 741 insertions, 0 deletions
diff --git a/src/build.y b/src/build.y
new file mode 100644
index 0000000..a6618e4
--- /dev/null
+++ b/src/build.y
@@ -0,0 +1,741 @@
1%defines
2%{ /* Prologue -- decls and stuff */
3 #include "buildparser.h"
4 #include "ast.h"
5void yyerror( YYLTYPE *locp, yyscan_t yyscanner, BuildParser &bld, const char *msg );
6%}
7/* Bison declerations */
8
9%parse-param { yyscan_t yyscanner }
10%parse-param { BuildParser &bld }
11%lex-param { yyscan_t yyscanner }
12%lex-param { BuildParser &bld }
13%pure-parser
14
15%locations
16
17%debug
18%error-verbose
19%name-prefix="build_"
20
21%union {
22 int iVal;
23 char *sVal;
24 float fVal;
25 bool bVal;
26}
27
28%token <sVal> STRING "string literal"
29%token <sVal> KEYWORD "keyword"
30%token <sVal> CONDITION "condition term"
31%token <sVal> VARIABLE "variable name"
32%token <sVal> FUNCTION "function name"
33%token <sVal> UNDEF "undefined identifier"
34%token <sVal> PROFILE "profile execute"
35%token <iVal> INT "integer literal"
36%token <fVal> FLOAT "floating point literal"
37%token <bVal> BOOL "boolean literal"
38
39%token TOK_TARGET "target"
40%token TOK_INPUT "input"
41%token TOK_OUTPUT "output"
42%token TOK_UNSET "unset"
43%token TOK_SET "set"
44%token TOK_CONDITION "condition"
45%token TOK_REQUIRES "requires"
46%token TOK_AUTO "auto"
47%token TOK_CONFIG "config"
48%token TOK_DISPLAY "display"
49%token TOK_TYPE "type"
50%token TOK_INT "int"
51%token TOK_FLOAT "float"
52%token TOK_BOOL "boolean"
53%token TOK_VERSION "version"
54%token TOK_STRING "string"
55%token TOK_DEFAULT "default"
56%token TOK_ALLOW "allow"
57%token TOK_RULE "rule"
58%token TOK_ACTION "action"
59%token TOK_PROFILE "profile"
60%token TOK_IF "if"
61%token TOK_THEN "then"
62%token TOK_ELSE "else"
63%token TOK_INCLUDE "include"
64%token TOK_ERROR "error"
65%token TOK_WARNING "warning"
66%token TOK_NOTICE "notice"
67%token TOK_CACHE "cache"
68%token TOK_ALWAYS "always"
69%token TOK_NEVER "never"
70%token TOK_GLOBAL "global"
71%token TOK_LOCAL "local"
72%token TOK_FOR "for"
73%token TOK_IN "in"
74%token TOK_DO "do"
75%token TOK_RETURN "return"
76%token TOK_FUNCTION "function"
77%token TOK_CONTINUE "continue"
78%token TOK_BREAK "break"
79%token TOK_VALUE "value"
80%token TOK_ALL "all"
81%token TOK_EXPORT "export"
82%token TOK_TAG "tag"
83%token TOK_NULL "null"
84
85%token OP_ADDSETP "+="
86%token OP_ADDSETR "<<"
87%token OP_CMPEQUAL "=="
88%token OP_INEQUAL "!="
89%token OP_LTEQUAL "<="
90%token OP_GTEQUAL ">="
91
92%token '(' ')' '{' '}' '[' ']' ',' ';' '=' '.' '<' '>' '+' '-' '*' '/'
93
94%right '=' OP_ADDSETP OPADDSETR
95%left OP_CMPEQUAL '<' '>' OP_INEQUAL OP_LTEQUAL OP_GTEQUAL '+' '-' '*' '/'
96%left '(' ')' '{' '}' '[' ']'
97%left IINEG IINOT
98
99%destructor { delete[] $$; } STRING
100%destructor { delete[] $$; } KEYWORD
101%destructor { delete[] $$; } CONDITION
102%destructor { delete[] $$; } VARIABLE
103%destructor { delete[] $$; } FUNCTION
104%destructor { delete[] $$; } UNDEF
105%destructor { delete[] $$; } PROFILE
106
107%% /* Grammar rules */
108
109/*
110 * root stuff
111 */
112
113root:
114// | root set
115 | root line_expr
116 | root unset
117 | root target
118 | root rule
119 | root config
120 | root root_if
121 | root root_for
122 | root include
123 | root notify
124 | root export
125 | root function_def
126 | root action_def
127 ;
128
129root_sub_exprs:
130// | root set
131 | root line_expr
132 | root unset
133 | root target
134 | root rule
135 | root config
136 | root root_if
137 | root root_for
138 | root include
139 | root notify
140 | root export
141 ;
142
143include: TOK_INCLUDE STRING ';' { bld.include( $2, yyscanner, &yylloc ); }
144 ;
145
146/*
147 * data related
148 */
149
150string: STRING { bld.xAst.addNode( AstNode::typeString, $1 ); }
151 ;
152
153int: INT { bld.xAst.addNode( AstNode::typeInt, $1 ); }
154 ;
155
156float: FLOAT { bld.xAst.addNode( AstNode::typeFloat, $1 ); }
157 ;
158
159bool: BOOL { bld.xAst.addNode( AstNode::typeBool, (bool)$1 ); }
160 ;
161
162null: TOK_NULL { bld.xAst.addNode( AstNode::typeNull ); }
163
164literal: string
165 | int
166 | float
167 | bool
168 | null
169 ;
170
171variable: UNDEF /*VARIABLE*/ { bld.xAst.addNode( AstNode::typeVariable, $1 ); }
172
173list_core:
174 | { bld.xAst.openBranch(); } expr
175 | list_core ',' { bld.xAst.openBranch(); } expr
176 ;
177
178list: '[' {
179 bld.xAst.addNode( AstNode::typeList );
180 } list_core ']' {
181 bld.xAst.closeNode();
182 }
183 ;
184
185value_mods:
186 | value_mods '.' function
187 ;
188
189value_core: variable
190 | literal
191 | function
192 | list
193 ;
194
195value: value_core value_mods
196 ;
197
198/*
199 * misc global things
200 */
201
202notify: TOK_ERROR STRING ';' { bld.xAst.addNode( AstNode::typeError, $2 ); }
203 | TOK_WARNING STRING ';' { bld.xAst.addNode( AstNode::typeWarning, $2 ); }
204 | TOK_NOTICE STRING ';' { bld.xAst.addNode( AstNode::typeNotice, $2 ); }
205 ;
206/*
207set_rhs: '=' { bld.xAst.addNode( AstNode::typeOpEq ); } value
208 | OP_ADDSETP { bld.xAst.addNode( AstNode::typeOpPlusEq ); } value
209 | OP_ADDSETR { bld.xAst.addNode( AstNode::typeOpPlusEqRaw ); } string
210 ;
211
212set: TOK_SET {
213 bld.xAst.addNode( AstNode::typeSet );
214 bld.xAst.openBranch();
215 } variable set_rhs ';' {
216 bld.xAst.closeNode();
217 }
218 ;*/
219
220unset: TOK_UNSET {
221 bld.xAst.addNode( AstNode::typeUnset );
222 bld.xAst.openBranch();
223 } variable ';' {
224 bld.xAst.closeNode();
225 }
226 ;
227
228export_rhs: '=' value
229 |
230 ;
231
232export: TOK_EXPORT {
233 bld.xAst.addNode( AstNode::typeExport );
234 bld.xAst.openBranch();
235 } variable export_rhs ';' {
236 bld.xAst.closeNode();
237 }
238 ;
239
240func_params:
241 | func_param_list
242 ;
243
244func_param_list: { bld.xAst.openBranch(); } value
245 | func_param_list ',' { bld.xAst.openBranch(); } value
246 ;
247
248function: UNDEF '(' {
249 bld.xAst.addNode( AstNode::typeFunction );
250 bld.xAst.openBranch();
251 bld.xAst.addNode( AstNode::typeString, $1 );
252 } func_params ')' {
253 bld.xAst.closeNode();
254 }
255 ;
256
257requires: TOK_REQUIRES {
258 bld.xAst.addNode( AstNode::typeRequires );
259 bld.xAst.openBranch();
260 } value ';' {
261 bld.xAst.closeNode();
262 }
263 ;
264
265type: TOK_STRING { bld.xAst.addNode( AstNode::typeTypeString ); }
266 | TOK_INT { bld.xAst.addNode( AstNode::typeTypeInt ); }
267 | TOK_FLOAT { bld.xAst.addNode( AstNode::typeTypeFloat ); }
268 | TOK_BOOL { bld.xAst.addNode( AstNode::typeTypeBool ); }
269 | TOK_VERSION { bld.xAst.addNode( AstNode::typeTypeVersion ); }
270 ;
271
272/*
273 * comparisons
274 */
275
276expr: value
277 | '(' expr ')'
278 | UNDEF '=' {
279 bld.xAst.addNode( AstNode::typeVariableRef, $1 );
280 } expr {
281 bld.xAst.addNode( AstNode::typeOpEq );
282 }
283 | UNDEF OP_ADDSETP {
284 bld.xAst.addNode( AstNode::typeVariableRef, $1 );
285 } expr {
286 bld.xAst.addNode( AstNode::typeOpPlusEq );
287 }
288 | expr OP_CMPEQUAL expr
289 {
290 bld.xAst.addNode( AstNode::typeCmpEq );
291 }
292 | expr '<' expr
293 {
294 bld.xAst.addNode( AstNode::typeCmpLt );
295 }
296 | expr '>' expr
297 {
298 bld.xAst.addNode( AstNode::typeCmpGt );
299 }
300 | expr OP_INEQUAL expr
301 {
302 bld.xAst.addNode( AstNode::typeCmpNe );
303 }
304 | expr OP_LTEQUAL expr
305 {
306 bld.xAst.addNode( AstNode::typeCmpLtEq );
307 }
308 | expr OP_GTEQUAL expr
309 {
310 bld.xAst.addNode( AstNode::typeCmpGtEq );
311 }
312 | expr '+' expr
313 {
314 bld.xAst.addNode( AstNode::typeOpPlus );
315 }
316 | expr '-' expr
317 {
318 bld.xAst.addNode( AstNode::typeOpMinus );
319 }
320 | expr '*' expr
321 {
322 bld.xAst.addNode( AstNode::typeOpMultiply );
323 }
324 | expr '/' expr
325 {
326 bld.xAst.addNode( AstNode::typeOpDivide );
327 }
328 | '-' expr %prec IINEG
329 {
330 bld.xAst.addNode( AstNode::typeOpNegate );
331 }
332 | '!' expr %prec IINOT
333 {
334 bld.xAst.addNode( AstNode::typeOpNot );
335 }
336 ;
337
338line_expr: {
339 bld.xAst.addNode( AstNode::typeExpr );
340 bld.xAst.openBranch();
341 } expr ';'
342 {
343 bld.xAst.closeNode();
344 }
345 ;
346
347if_core: TOK_IF {
348 bld.xAst.addNode( AstNode::typeIf );
349 bld.xAst.openBranch();
350// bld.xAst.addNode( AstNode::typeExpr );
351// bld.xAst.openBranch();
352 } expr TOK_THEN {
353// bld.xAst.closeNode();
354 bld.xAst.openBranch();
355 }
356 ;
357
358else: TOK_ELSE { bld.xAst.openBranch(); }
359 ;
360
361root_if: if_core '{' root_sub_exprs '}' root_else { bld.xAst.closeNode(); }
362 ;
363
364root_else:
365 | else '{' root_sub_exprs '}'
366 | else root_if
367 ;
368
369target_if: if_core '{' target_exprs '}' target_else { bld.xAst.closeNode(); }
370 ;
371
372target_else:
373 | else '{' target_exprs '}'
374 | else target_if
375 ;
376
377rule_if: if_core '{' rule_exprs '}' rule_else { bld.xAst.closeNode(); }
378 ;
379
380rule_else:
381 | else '{' rule_exprs '}'
382 | else rule_if
383 ;
384
385function_if: if_core '{' function_exprs '}' function_else
386 { bld.xAst.closeNode(); }
387 ;
388
389function_else:
390 | else '{' function_exprs '}'
391 | else function_if
392 ;
393
394/*
395 * loops
396 */
397
398for_base: TOK_FOR {
399 bld.xAst.addNode( AstNode::typeFor );
400 bld.xAst.openBranch();
401 } variable TOK_IN {
402 bld.xAst.openBranch();
403 } value TOK_DO {
404 bld.xAst.openBranch();
405 }
406 ;
407
408root_for: for_base '{' root_sub_exprs '}' { bld.xAst.closeNode(); }
409 ;
410
411target_for: for_base '{' target_exprs '}' { bld.xAst.closeNode(); }
412 ;
413
414rule_for: for_base '{' rule_exprs '}' { bld.xAst.closeNode(); }
415 ;
416
417function_for: for_base '{' function_exprs '}' { bld.xAst.closeNode(); }
418 ;
419
420/*
421 * functions
422 */
423
424function_def: TOK_FUNCTION UNDEF {
425 bld.xAst.addNode( AstNode::typeFunctionDef );
426 bld.xAst.openBranch();
427 bld.xAst.addNode( AstNode::typeString, $2 );
428 bld.xAst.openBranch();
429 } '(' param_defs ')' {
430 bld.xAst.openBranch();
431 } '{' function_exprs '}' {
432 bld.xAst.closeNode();
433 }
434 ;
435
436param_defs:
437 | param_def_list
438 ;
439
440param_def_list: variable
441 | param_def_list ',' variable
442 ;
443
444function_exprs:
445// | function_exprs function ';'
446// | function_exprs set
447 | function_exprs unset
448 | function_exprs line_expr
449 | function_exprs export
450 | function_exprs notify
451 | function_exprs function_if
452 | function_exprs function_for
453 | function_exprs return
454 | function_exprs process_target
455 ;
456
457return: TOK_RETURN {
458 bld.xAst.addNode( AstNode::typeReturn );
459 bld.xAst.openBranch();
460 } expr {
461 bld.xAst.closeNode();
462 } ';'
463 ;
464
465/*
466 * Actions, they're basically functions, no parameters
467 */
468
469action_def: TOK_ACTION STRING {
470 bld.xAst.addNode( AstNode::typeActionDef );
471 bld.xAst.openBranch();
472 bld.xAst.addNode( AstNode::typeString, $2 );
473 bld.xAst.openBranch();
474 } '{' function_exprs '}' {
475 bld.xAst.closeNode();
476 }
477 ;
478
479/*
480 * profiles
481 */
482
483profile: TOK_PROFILE {
484 bld.xAst.addNode( AstNode::typeProfile );
485 bld.xAst.openBranch();
486 } string {
487 bld.xAst.openBranch();
488 } '{' profile_exprs '}' {
489 bld.xAst.closeNode();
490 } /* in-line function */
491 ;
492
493profile_exprs:
494// | profile_exprs function ';'
495// | profile_exprs set
496 | profile_exprs unset
497 | profile_exprs line_expr
498 | profile_exprs export
499 | profile_exprs notify
500 | profile_exprs function_if
501 | profile_exprs function_for
502 | profile_exprs return
503 | profile_exprs process_target
504 | profile_exprs condition
505 ;
506/*
507 * targets
508 */
509
510target: TOK_TARGET {
511 bld.xAst.addNode( AstNode::typeTarget );
512 bld.xAst.openBranch();
513 } expr {
514 bld.xAst.openBranch();
515 } '{' target_exprs '}' {
516 bld.xAst.closeNode();
517 }
518 ;
519
520target_exprs:
521// | target_exprs set
522 | target_exprs unset
523 | target_exprs line_expr
524 | target_exprs export
525 | target_exprs target_input
526 | target_exprs requires
527 | target_exprs profile
528 | target_exprs target_if
529 | target_exprs target_for
530 | target_exprs notify
531 | target_exprs target_rule
532 | target_exprs tag
533 | target_exprs display
534 ;
535
536target_input: TOK_INPUT {
537 bld.xAst.addNode( AstNode::typeInput );
538 bld.xAst.openBranch();
539 } expr ';' {
540 bld.xAst.closeNode();
541 }
542 ;
543
544target_rule: TOK_RULE {
545 bld.xAst.addNode( AstNode::typeRule );
546 bld.xAst.openBranch();
547 } string ';' {
548 bld.xAst.closeNode();
549 }
550 ;
551
552condition: TOK_CONDITION CONDITION ';' {
553 bld.xAst.addNode( AstNode::typeCondition, $2 );
554 }
555 | TOK_CONDITION TOK_ALWAYS ';'{
556 bld.xAst.addNode( AstNode::typeCondition, "always" );
557 }
558 | TOK_CONDITION TOK_NEVER ';'{
559 bld.xAst.addNode( AstNode::typeCondition, "never" );
560 }
561 ;
562
563/*
564 * rules
565 */
566
567rule: TOK_RULE {
568 bld.xAst.addNode( AstNode::typeRuleDef );
569 bld.xAst.openBranch();
570 } string {
571 bld.xAst.openBranch();
572 } '{' rule_exprs '}' {
573 bld.xAst.closeNode();
574 }
575 ;
576
577rule_exprs:
578 | rule_exprs rule_input
579 | rule_exprs output
580 | rule_exprs requires
581 | rule_exprs profile
582 | rule_exprs rule_if
583 | rule_exprs rule_for
584 | rule_exprs notify
585 | rule_exprs display
586 | rule_exprs tag
587// | rule_exprs set
588 ;
589
590rule_input_func: function
591 | STRING {
592 /* In this case, when the input is just a string,
593 lets actually turn it into a call to the matches function.
594 */
595 bld.xAst.addNode( AstNode::typeFunction );
596 bld.xAst.openBranch();
597 bld.xAst.addNode( AstNode::typeString, "matches" );
598 bld.xAst.openBranch();
599 bld.xAst.addNode( AstNode::typeString, $1 );
600 bld.xAst.closeNode();
601 }
602/* | string */
603 ;
604
605rule_input: TOK_INPUT {
606 bld.xAst.addNode( AstNode::typeInput );
607 bld.xAst.openBranch();
608 } rule_input_func ';' {
609 bld.xAst.closeNode();
610 }
611 ;
612
613output: TOK_OUTPUT {
614 bld.xAst.addNode( AstNode::typeOutput );
615 bld.xAst.openBranch();
616 } value ';' {
617 bld.xAst.closeNode();
618 }
619 ;
620
621/*
622 * config
623 */
624config: TOK_CONFIG {
625 bld.xAst.addNode( AstNode::typeConfig );
626 bld.xAst.openBranch();
627 } string {
628 bld.xAst.openBranch();
629 } '{' config_exprs '}' {
630 bld.xAst.closeNode();
631 }
632 | TOK_AUTO TOK_CONFIG {
633 bld.xAst.addNode( AstNode::typeAutoConfig );
634 bld.xAst.openBranch();
635 } string {
636 bld.xAst.openBranch();
637 } '{' config_exprs '}' {
638 bld.xAst.closeNode();
639 }
640 | TOK_GLOBAL TOK_CONFIG {
641 bld.xAst.addNode( AstNode::typeGlobalConfig );
642 bld.xAst.openBranch();
643 } string {
644 bld.xAst.openBranch();
645 } '{' config_exprs '}' {
646 bld.xAst.closeNode();
647 }
648 ;
649
650config_exprs:
651 | config_exprs display
652 | config_exprs config_type
653 | config_exprs default
654 | config_exprs value_key
655 | config_exprs allow
656 | config_exprs cache
657 ;
658
659display: TOK_DISPLAY STRING ';' {
660 bld.xAst.addNode( AstNode::typeDisplay, $2 );
661 }
662 ;
663
664config_type: TOK_TYPE {
665 bld.xAst.addNode( AstNode::typeType );
666 bld.xAst.openBranch();
667 } type ';' {
668 bld.xAst.closeNode();
669 }
670 ;
671
672default: TOK_DEFAULT {
673 bld.xAst.addNode( AstNode::typeDefault );
674 bld.xAst.openBranch();
675 } literal ';' {
676 bld.xAst.closeNode();
677 }
678 ;
679
680value_key_val: value ';'
681 | '{' function_exprs '}' /* inline function */
682
683value_key: TOK_VALUE {
684 bld.xAst.addNode( AstNode::typeValue );
685 bld.xAst.openBranch();
686 } value_key_val {
687 bld.xAst.closeNode();
688 }
689 ;
690
691allow: TOK_ALLOW {
692 bld.xAst.addNode( AstNode::typeAllow );
693 bld.xAst.openBranch();
694 } value ';' {
695 bld.xAst.closeNode();
696 }
697 ;
698
699cache: TOK_CACHE TOK_ALWAYS ';'
700 { bld.xAst.addNode( AstNode::typeCache, true ); }
701 | TOK_CACHE TOK_NEVER ';'
702 { bld.xAst.addNode( AstNode::typeCache, false ); }
703 ;
704
705/*
706 * target/profile execute
707 */
708process_target: PROFILE
709 {
710 bld.xAst.addNode( AstNode::typeProcessTarget );
711 bld.xAst.openBranch();
712 bld.xAst.addNode( AstNode::typeString, $1 );
713 bld.xAst.openBranch();
714 } value ';' {
715 bld.xAst.closeNode();
716 }
717 ;
718
719tag: TOK_TAG
720 {
721 bld.xAst.addNode( AstNode::typeTag );
722 bld.xAst.openBranch();
723 } value ';' {
724 bld.xAst.closeNode();
725 }
726 ;
727
728
729%%
730
731/* Epilogue -- whatever you want, functions mainly */
732
733void build_error( YYLTYPE *locp, yyscan_t, BuildParser &bld, const char *msg )
734{
735 bld.error(
736 locp->first_line, locp->last_line,
737 locp->first_column, locp->last_column,
738 msg
739 );
740}
741