2 /*+------- <| --------------------------------------------------------**
4 **--- /.\ -----------------------------------------------------**
5 ** <| [""M# parser.y **
6 **- A | # -----------------------------------------------------**
7 ** /.\ [""M# First version: 30/04/2008 **
8 **- [""M# | # U"U#U -----------------------------------------------**
11 ****** | "--' .-" ******************************************************
12 * |"-"-"-"-"-#-#-## Clan : the Chunky Loop Analyzer (experimental) *
13 **** | # ## ###### *****************************************************
15 * \ ::::'/ Copyright (C) 2008 Cedric Bastoul *
17 * ::88a ### This is free software; you can redistribute it *
18 * ::::888a 8a ##::. and/or modify it under the terms of the GNU Lesser *
19 * ::::::::888a88a[]::: General Public License as published by the Free *
20 *::8:::::::::SUNDOGa8a::. Software Foundation, either version 3 of the *
21 *::::::::8::::888:Y8888:: License, or (at your option) any later version. *
22 *::::':::88::::888::Y88a::::::::::::... *
23 *::'::.. . ..... .. ... . *
24 * This software is distributed in the hope that it will be useful, but *
25 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
26 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
29 * You should have received a copy of the GNU Lesser General Public License *
30 * along with software; if not, write to the Free Software Foundation, Inc., *
31 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
33 * Clan, the Chunky Loop Analyzer *
34 * Written by Cedric Bastoul, Cedric.Bastoul@inria.fr *
36 ******************************************************************************/
44 #include <clan/macros.h>
45 #include <clan/vector.h>
46 #include <clan/matrix.h>
47 #include <clan/scop.h>
48 #include <clan/symbol.h>
49 #include <clan/statement.h>
50 #include <clan/options.h>
54 int clan_parse_error
= 0; /**< Set to 1 during parsing if
55 encountered an error */
56 void clan_parser_log
(char *);
57 scoplib_scop_p clan_parse
(FILE *, clan_options_p
);
59 extern
FILE * yyin
; /**< File to be read by Lex */
60 extern
char scanner_latest_text
[]; /**< Latest text read by Lex */
62 /* This is the "parser state", a collection of variables that vary
63 * during the parsing and thanks to we can extract all SCoP informations.
65 scoplib_scop_p parser_scop
; /**< SCoP in construction */
66 scoplib_statement_p parser_statement
; /**< Statement in construction */
67 clan_symbol_p parser_symbol
; /**< Top of the symbol table */
68 int parser_recording
; /**< Boolean: do we record or not? */
69 char * parser_record
; /**< What we record
71 int parser_depth
= 0; /**< Current loop depth */
72 int * parser_scheduling
; /**< Current statement scheduling */
73 clan_symbol_p
* parser_iterators
; /**< Current iterator list */
74 scoplib_matrix_p parser_domain
; /**< Current iteration domain */
75 int parser_nb_cons
= 0; /**< Current number of constraints */
76 int * parser_consperdim
; /**< Constraint nb for each
78 int* parser_variables_localvars
;/**< List of variables
81 int* parser_variables_liveout
;/**< List of variables
84 /* Ugly global variable to keep/read Clan options during parsing. */
85 clan_options_p parser_options
= NULL
;
90 %
union { int value
; /**< An integer value for integers */
91 char * symbol
; /**< A string for identifiers */
92 scoplib_vector_p affex
; /**< An affine expression */
93 scoplib_matrix_p setex
; /**< A set of affine expressions */
94 scoplib_matrix_p rw
[2]; /**< Read and write array accesses */
98 %token IF ELSE FOR PRAGMALOCALVARS PRAGMALIVEOUT
99 %token MIN MAX CEILD FLOORD
102 %token
<value
> INTEGER
104 %token syRPARENTHESIS syLPARENTHESIS syRBRACKET syLBRACKET syRBRACE syLBRACE
105 %token sySEMICOLON syCOMMA syPOINT syARROW
107 %token opEQUAL opLEQ opGEQ opLOWER opGREATER opPLUS opMINUS
108 %token opINCREMENTATION opDECREMENTATION opNOT
109 %token opMULTIPLY opDIVIDE opMOD opAND opOR opCOMP
111 %token opPLUSEQUAL opMINUSEQUAL opMULTIPLYEQUAL opDIVIDEEQUAL
112 %token opMODEQUAL opANDEQUAL opOREQUAL opCOMPEQUAL
113 %token opLAND opLOR opQMARK opCOLON
116 %left opMULTIPLY opDIVIDE opMOD opAND opOR opCOMP
117 %left opEQUAL opLEQ opGEQ opLOWER opGREATER opLAND opCOLON opQMARK
119 %left MAXPRIORITY
/* Dummy token to help in removing shift/reduce conflicts */
121 %type
<setex
> condition
122 %type
<setex
> min_affine_expression
123 %type
<setex
> max_affine_expression
124 %type
<affex
> affine_expression
126 %type
<setex
> array_index
127 %type
<setex
> variable
128 %type
<setex
> variable_list
129 %type
<setex
> expression
130 %type
<rw
> assignment
142 /* The full program was parsed. Allocate and fill the final
144 int nb_parameters
, nb_arrays
;
146 parser_scop
->parameters
= clan_symbol_id_array
(parser_symbol
,
147 SCOPLIB_TYPE_PARAMETER
,
149 parser_scop
->nb_parameters
= nb_parameters
;
150 parser_scop
->arrays
= clan_symbol_id_array
(parser_symbol
,
153 parser_scop
->nb_arrays
= nb_arrays
;
154 if
(parser_options
->bounded_context
)
156 parser_scop
->context
= scoplib_matrix_malloc
(nb_parameters
,
159 for
(i
= 0; i
< nb_parameters
; ++i
)
161 SCOPVAL_set_si
(parser_scop
->context
->p
[i
][0], 1);
162 SCOPVAL_set_si
(parser_scop
->context
->p
[i
][i
+1], 1);
163 SCOPVAL_set_si
(parser_scop
->context
->p
[i
][nb_parameters
+1], 1);
167 parser_scop
->context
= scoplib_matrix_malloc
(0,nb_parameters
+2);
173 * Rules for a list of instructions
178 | instruction_list instruction
180 | instruction_list IGNORE
181 | syRBRACE instruction_list syLBRACE
186 * Rules for a bloc of instructions.
190 * Rule 1: bloc -> instruction
194 * Rule 2: bloc -> { instruction_list }
196 | syRBRACE instruction_list syLBRACE
201 * Rules for a program instruction. Either a for(..., if(..., or a
207 * Rule 1: instruction -> for ( id = <setex>; condition; increment) bloc
214 clan_symbol_p symbol
;
215 symbol
= clan_symbol_add
(&parser_symbol
,$3,
216 SCOPLIB_TYPE_ITERATOR
,parser_depth
+1);
217 /* Ensure that the returned symbol was either a new one,
218 either from the same type. */
219 if
(symbol
->type
!= SCOPLIB_TYPE_ITERATOR
)
221 yyerror("[Clan] Error: the input file is not a SCoP\n"
222 "\t> A loop iterator was previously used as a parameter"
226 /* Update the rank, in case a symbol with the same name was
228 if
(symbol
->rank
!= parser_depth
+ 1)
229 symbol
->rank
= parser_depth
+ 1;
230 parser_iterators
[parser_depth
] = symbol
;
231 /* Memorize the current iterator as a negative constraint prefix */
234 max_affine_expression
236 scoplib_vector_p parser_i_term
= clan_vector_term
(parser_symbol
,1,$3);
237 scoplib_vector_tag_inequality
(parser_i_term
);
239 for
(i
= 0; i
< $6->NbRows
; ++i
)
241 for
(j
= 1; j
< $6->NbColumns
; ++j
)
242 SCOPVAL_oppose
($6->p
[i
][j
],$6->p
[i
][j
]);
243 scoplib_matrix_add_vector
($6,parser_i_term
,i
);
245 scoplib_matrix_insert_matrix
(parser_domain
,$6,parser_nb_cons
);
247 parser_nb_cons
+= $6->NbRows
;
248 parser_consperdim
[parser_depth
] += $6->NbRows
;
249 scoplib_vector_free
(parser_i_term
);
251 scoplib_matrix_free
($6);
256 scoplib_matrix_insert_matrix
(parser_domain
,$9,parser_nb_cons
);
257 parser_nb_cons
+= $9->NbRows
;
258 parser_consperdim
[parser_depth
] += $9->NbRows
;
265 parser_scheduling
[parser_depth
] = 0;
270 parser_scheduling
[parser_depth
]++;
271 parser_nb_cons
-= parser_consperdim
[parser_depth
];
272 parser_consperdim
[parser_depth
] = 0;
273 clan_symbol_remove
(&parser_symbol
, parser_iterators
[parser_depth
]);
276 * Rule 2: instruction -> if (condition) bloc
279 | IF syRPARENTHESIS condition syLPARENTHESIS
281 /* Insert the condition constraint in the current parser domain. */
282 scoplib_matrix_insert_matrix
(parser_domain
,$3,parser_nb_cons
);
283 parser_nb_cons
+= $3->NbRows
;
287 parser_nb_cons
-= $3->NbRows
;
288 /* Remove the condition constraint from the current parser domain. */
290 for
(i
= parser_nb_cons
; i
< parser_domain
->NbRows
- 1; ++i
)
291 for
(j
= 0; j
< parser_domain
->NbColumns
; ++j
)
292 SCOPVAL_assign
(parser_domain
->p
[i
][j
],parser_domain
->p
[i
+1][j
]);
295 * Rule 3: instruction -> assignment
299 parser_statement
= scoplib_statement_malloc
();
300 parser_record
= (char *)malloc
(SCOPLIB_MAX_STRING
* sizeof
(char));
301 parser_recording
= CLAN_TRUE
;
302 /* Yacc needs Lex to read the next token to ensure we are starting
303 * an assignment. So we keep track of the latest text Lex read
304 * and we start the statement body with it.
306 strcpy
(parser_record
,scanner_latest_text
);
310 /* Deal with statements without surrounding loop by adding a
312 int old_parser_depth
= parser_depth
;
313 if
(parser_depth
== 0)
315 char* fakeiter
= strdup
("fakeiter");
316 clan_symbol_p symbol
= clan_symbol_lookup
(parser_symbol
, fakeiter
);
320 symbol
= clan_symbol_add
(&parser_symbol
,fakeiter
,
321 SCOPLIB_TYPE_ITERATOR
,parser_depth
+1);
322 parser_iterators
[parser_depth
] = symbol
;
323 scoplib_vector_p constraint
=
324 scoplib_vector_malloc
(parser_domain
->NbColumns
);
325 SCOPVAL_set_si
(constraint
->p
[1],1);
327 scoplib_matrix_replace_vector
(parser_domain
,constraint
,parser_nb_cons
);
329 scoplib_vector_free
(constraint
);
331 /* Construct the statement structure from the parser state */
332 parser_statement
->domain
= scoplib_matrix_list_malloc
();
333 parser_statement
->domain
->elt
= scoplib_matrix_ncopy
(parser_domain
,
335 parser_statement
->schedule
= clan_matrix_scheduling
(parser_scheduling
,
337 parser_statement
->read
= $2[0];
338 parser_statement
->write
= $2[1];
339 parser_statement
->body
= parser_record
;
340 parser_statement
->nb_iterators
= parser_depth
;
341 parser_statement
->iterators
= clan_symbol_iterators
(parser_iterators
,
343 if
(parser_statement
->write
== NULL
)
344 parser_statement
->write
=
345 scoplib_matrix_malloc
(0, parser_domain
->NbColumns
);
346 if
(parser_statement
->read
== NULL
)
347 parser_statement
->read
=
348 scoplib_matrix_malloc
(0, parser_domain
->NbColumns
);
349 parser_recording
= CLAN_FALSE
;
350 scoplib_statement_add
(&(parser_scop
->statement
),parser_statement
);
351 /* We were parsing a statement without iterator. Restore the
353 if
(old_parser_depth
== 0)
357 parser_consperdim
[parser_depth
] = 0;
359 parser_scheduling
[parser_depth
]++;
362 * Rule 4: instruction -> #pragma local-vars <vars>
363 * NOTE: THIS RULE IS REPONSIBLE FOR 10 shift/reduce conflicts.
364 * It is ok, though, the parsing will be correct.
366 | PRAGMALOCALVARS variable_list
369 scoplib_matrix_p m
= $2;
370 for
(i
= 0; i
< m
->NbRows
; ++i
)
372 int id
= SCOPVAL_get_si
(m
->p
[i
][0]);
373 for
(j
= 0; parser_variables_localvars
[j
] != -1 &&
374 parser_variables_localvars
[j
] != id
; ++j
)
376 if
(j
== CLAN_MAX_LOCAL_VARIABLES
)
378 yyerror("[Clan] Error: maximum number of local variables reached\n");
381 if
(parser_variables_localvars
[j
] == -1)
382 parser_variables_localvars
[j
] = id
;
386 * Rule 5: instruction -> #pragma live-out <vars>
387 * NOTE: THIS RULE IS REPONSIBLE FOR 10 shift/reduce conflicts.
388 * It is ok, though, the parsing will be correct.
390 | PRAGMALIVEOUT variable_list
393 scoplib_matrix_p m
= $2;
394 for
(i
= 0; i
< m
->NbRows
; ++i
)
396 int id
= SCOPVAL_get_si
(m
->p
[i
][0]);
397 for
(j
= 0; parser_variables_liveout
[j
] != -1 &&
398 parser_variables_liveout
[j
] != id
; ++j
)
400 if
(j
== CLAN_MAX_LOCAL_VARIABLES
)
402 yyerror("[Clan] Error: maximum number of live-out variables reached\n");
405 if
(parser_variables_liveout
[j
] == -1)
406 parser_variables_liveout
[j
] = id
;
413 * Rules for the for loop increment.
415 * i++, ++i, i = i + 1, i += 1
423 | opINCREMENTATION id
427 | id opASSIGNMENT id opPLUS INTEGER
431 yyerror("[Clan] Error: loop increment is not 1\n");
437 | id opPLUSEQUAL INTEGER
441 yyerror("[Clan] Error: loop increment is not 1\n");
450 * Reduction rules for min(... operators.
454 min_affine_expression:
457 $$
= scoplib_matrix_from_vector
($1);
458 scoplib_vector_free
($1);
460 | MIN syRPARENTHESIS min_affine_expression syCOMMA min_affine_expression
463 $$
= scoplib_matrix_concat
($3, $5);
469 * Reduction rules for max(... operators.
473 max_affine_expression:
476 $$
= scoplib_matrix_from_vector
($1);
477 scoplib_vector_free
($1);
479 | MAX syRPARENTHESIS max_affine_expression syCOMMA max_affine_expression
482 $$
= scoplib_matrix_concat
($3, $5);
488 * Reduction rules for affine expression.
497 | affine_expression opPLUS affine_expression
499 $$
= scoplib_vector_add
($1,$3);
500 scoplib_vector_free
($1);
501 scoplib_vector_free
($3);
503 | affine_expression opMINUS affine_expression
505 $$
= scoplib_vector_sub
($1,$3);
506 scoplib_vector_free
($1);
507 scoplib_vector_free
($3);
509 | syRPARENTHESIS affine_expression syLPARENTHESIS
513 | CEILD syRPARENTHESIS affine_expression syCOMMA term syLPARENTHESIS
515 SCOPVAL_assign
($3->p
[0], $5->p
[$5->Size
- 1]);
518 | FLOORD syRPARENTHESIS affine_expression syCOMMA term syLPARENTHESIS
520 SCOPVAL_assign
($3->p
[0], $5->p
[$5->Size
- 1]);
527 * Reduction rules for a term.
533 * Rule 1: term -> INT
537 $$
= clan_vector_term
(parser_symbol
,$1,NULL
);
544 clan_symbol_add
(&parser_symbol
,$1,SCOPLIB_TYPE_UNKNOWN
,parser_depth
);
545 $$
= clan_vector_term
(parser_symbol
,1,$1);
549 * Rule 3: term -> - INT
553 $$
= clan_vector_term
(parser_symbol
,-($2),NULL
);
556 * Rule 4: term -> INT * id
558 | INTEGER opMULTIPLY id
560 clan_symbol_add
(&parser_symbol
,$3,SCOPLIB_TYPE_UNKNOWN
,parser_depth
);
561 $$
= clan_vector_term
(parser_symbol
,$1,$3);
565 * Rule 4': term -> id * INT
567 | id opMULTIPLY INTEGER
569 clan_symbol_add
(&parser_symbol
,$1,SCOPLIB_TYPE_UNKNOWN
,parser_depth
);
570 $$
= clan_vector_term
(parser_symbol
,$3,$1);
574 * Rule 5: term -> INT * INT
576 | INTEGER opMULTIPLY INTEGER
578 $$
= clan_vector_term
(parser_symbol
, ($1) * ($3), NULL
);
581 * Rule 6: term -> INT / INT
583 | INTEGER opDIVIDE INTEGER
585 $$
= clan_vector_term
(parser_symbol
, ($1) / ($3), NULL
);
588 * Rule 7: term -> - INT * id
590 | opMINUS INTEGER opMULTIPLY id
592 clan_symbol_add
(&parser_symbol
,$4,SCOPLIB_TYPE_UNKNOWN
,parser_depth
);
593 $$
= clan_vector_term
(parser_symbol
,-($2),$4);
597 * Rule 7': term -> - id * INT
599 | opMINUS id opMULTIPLY INTEGER
601 clan_symbol_add
(&parser_symbol
,$2,SCOPLIB_TYPE_UNKNOWN
,parser_depth
);
602 $$
= clan_vector_term
(parser_symbol
,-($4),$2);
606 * Rule 8: term -> - id
610 clan_symbol_add
(&parser_symbol
,$2,SCOPLIB_TYPE_UNKNOWN
,parser_depth
);
611 $$
= clan_vector_term
(parser_symbol
,-1,$2);
618 * Rules for defining a condition. A condition is an affine expression
619 * (possibly with min/max operator(s)) of the form 'affex1 op affex2'
620 * where affex2 may contain min operators iff op is '<' or '<=', and
621 * max operators iff op is '>' or '>='.
626 * Rule 1: condition -> <affex> < min_affex
628 affine_expression opLOWER min_affine_expression
630 /* a<b translates to -a+b-1>=0 */
632 scoplib_vector_p tmp
= scoplib_vector_add_scalar
($1,1);
633 scoplib_vector_tag_inequality
(tmp
);
634 for
(i
= 0; i
< $3->NbRows
; ++i
)
636 /* We have parsed a ceild/floord at an earlier stage. */
637 if
(SCOPVAL_notzero_p
($3->p
[i
][0]) && !SCOPVAL_one_p
($3->p
[i
][0]))
639 scoplib_int_t val
; SCOPVAL_init
(val
);
640 SCOPVAL_assign
(val
, $3->p
[i
][0]);
641 SCOPVAL_set_si
($3->p
[i
][0], 0);
642 scoplib_vector_p tmp2
= scoplib_vector_add_scalar
($1,0);
644 for
(j
= 1; j
< $1->Size
; ++j
)
645 SCOPVAL_multo
(tmp2
->p
[j
], $1->p
[j
], val
);
646 scoplib_vector_p tmp3
= scoplib_vector_add_scalar
(tmp2
,1);
647 scoplib_vector_tag_inequality
(tmp3
);
648 scoplib_matrix_sub_vector
($3, tmp3
, i
);
649 scoplib_vector_free
(tmp2
);
650 scoplib_vector_free
(tmp3
);
654 scoplib_matrix_sub_vector
($3, tmp
, i
);
656 scoplib_vector_free
($1);
657 scoplib_vector_free
(tmp
);
661 * Rule 2: condition -> <affex> > max_affex
663 | affine_expression opGREATER max_affine_expression
665 /* a>b translates to a-b-1>=0 */
667 scoplib_vector_p tmp
= scoplib_vector_add_scalar
($1,-1);
668 scoplib_vector_tag_inequality
(tmp
);
669 for
(i
= 0; i
< $3->NbRows
; ++i
)
671 for
(j
= 1; j
< $3->NbColumns
; ++j
)
672 SCOPVAL_oppose
($3->p
[i
][j
],$3->p
[i
][j
]);
673 /* We have parsed a ceild/floord at an earlier stage. */
674 if
(SCOPVAL_notzero_p
($3->p
[i
][0]) && !SCOPVAL_one_p
($3->p
[i
][0]))
676 scoplib_int_t val
; SCOPVAL_init
(val
);
677 SCOPVAL_assign
(val
, $3->p
[i
][0]);
678 SCOPVAL_set_si
($3->p
[i
][0], 0);
679 scoplib_vector_p tmp2
= scoplib_vector_add_scalar
($1,0);
681 for
(j
= 1; j
< $1->Size
; ++j
)
682 SCOPVAL_multo
(tmp2
->p
[j
], $1->p
[j
], val
);
683 scoplib_vector_p tmp3
= scoplib_vector_add_scalar
(tmp2
,-1);
684 scoplib_vector_tag_inequality
(tmp3
);
685 scoplib_matrix_add_vector
($3, tmp3
, i
);
686 scoplib_vector_free
(tmp2
);
687 scoplib_vector_free
(tmp3
);
691 scoplib_matrix_add_vector
($3,tmp
,i
);
693 scoplib_vector_free
($1);
694 scoplib_vector_free
(tmp
);
698 * Rule 3: condition -> <affex> <= min_affex
700 | affine_expression opLEQ min_affine_expression
702 /* a<=b translates to -a+b>=0 */
704 scoplib_vector_p tmp
= scoplib_vector_add_scalar
($1,0);
705 scoplib_vector_tag_inequality
(tmp
);
706 for
(i
= 0; i
< $3->NbRows
; ++i
)
708 /* We have parsed a ceild/floord at an earlier stage. */
709 if
(SCOPVAL_notzero_p
($3->p
[i
][0]) && !SCOPVAL_one_p
($3->p
[i
][0]))
711 scoplib_int_t val
; SCOPVAL_init
(val
);
712 SCOPVAL_assign
(val
, $3->p
[i
][0]);
713 SCOPVAL_set_si
($3->p
[i
][0], 0);
714 scoplib_vector_p tmp2
= scoplib_vector_add_scalar
($1,0);
716 for
(j
= 1; j
< $1->Size
; ++j
)
717 SCOPVAL_multo
(tmp2
->p
[j
], $1->p
[j
], val
);
718 scoplib_vector_tag_inequality
(tmp2
);
719 scoplib_matrix_sub_vector
($3, tmp2
, i
);
720 scoplib_vector_free
(tmp2
);
724 scoplib_matrix_sub_vector
($3,tmp
,i
);
726 scoplib_vector_free
($1);
727 scoplib_vector_free
(tmp
);
731 * Rule 4: condition -> <affex> >= max_affex
733 | affine_expression opGEQ max_affine_expression
735 /* a>=b translates to a-b>=0 */
737 scoplib_vector_p tmp
= scoplib_vector_add_scalar
($1,0);
738 scoplib_vector_tag_inequality
(tmp
);
739 for
(i
= 0; i
< $3->NbRows
; ++i
)
741 for
(j
= 1; j
< $3->NbColumns
; ++j
)
742 SCOPVAL_oppose
($3->p
[i
][j
],$3->p
[i
][j
]);
743 /* We have parsed a ceild/floord at an earlier stage. */
744 if
(SCOPVAL_notzero_p
($3->p
[i
][0]) && !SCOPVAL_one_p
($3->p
[i
][0]))
746 scoplib_int_t val
; SCOPVAL_init
(val
);
747 SCOPVAL_assign
(val
, $3->p
[i
][0]);
748 SCOPVAL_set_si
($3->p
[i
][0], 0);
749 scoplib_vector_p tmp2
= scoplib_vector_add_scalar
($1,0);
751 for
(j
= 1; j
< $1->Size
; ++j
)
752 SCOPVAL_multo
(tmp2
->p
[j
], $1->p
[j
], val
);
753 scoplib_vector_tag_inequality
(tmp2
);
754 scoplib_matrix_add_vector
($3, tmp2
, i
);
755 scoplib_vector_free
(tmp2
);
759 scoplib_matrix_add_vector
($3,tmp
,i
);
761 scoplib_vector_free
($1);
762 scoplib_vector_free
(tmp
);
766 * Rule 5: condition -> <affex> == <affex>
768 | affine_expression opEQUAL affine_expression
770 /* a==b translates to a-b==0 */
771 /* Warning: cases like ceild(M,32) == ceild(N,32) are not handled.
772 Assert if we encounter such a case. */
773 assert
((SCOPVAL_zero_p
($1->p
[0]) || SCOPVAL_one_p
($1->p
[0]))
774 && (SCOPVAL_zero_p
($3->p
[0]) || SCOPVAL_one_p
($3->p
[0])));
775 scoplib_vector_p res
= scoplib_vector_sub
($1,$3);
776 scoplib_vector_tag_equality
(res
);
777 $$
= scoplib_matrix_from_vector
(res
);
778 scoplib_vector_free
(res
);
779 scoplib_vector_free
($1);
780 scoplib_vector_free
($3);
783 * Rule 6: condition -> ( condition )
785 | syRPARENTHESIS condition syLPARENTHESIS
790 * Rule 7: condition -> condition && condition
792 | condition opLAND condition
794 $$
= scoplib_matrix_concat
($1,$3);
795 scoplib_matrix_free
($1);
796 scoplib_matrix_free
($3);
802 * Shortcut rules for reduction operators (+=, -=, ...)
818 * Shortcut rules for unary increment/decrement operators (-- and ++)
828 * Rules for an assignment (an instruction which is not a 'for' nor an 'if')
834 * Rule 1: assignment -> var = expression;
836 variable opASSIGNMENT expression sySEMICOLON
840 yyerror ("[Clan] Error: changing value of iterator/parameter");
847 * Rule 2: assignment -> var red_op expression;
849 | variable reduction_operator expression sySEMICOLON
853 yyerror ("[Clan] Error: changing value of iterator/parameter");
856 $$
[0] = scoplib_matrix_concat
($1,$3);
857 scoplib_matrix_free
($3);
861 * Rule 3: assignment -> var un_op;
863 | variable unary_operator sySEMICOLON
867 yyerror ("[Clan] Error: changing value of iterator/parameter");
871 $$
[1] = scoplib_matrix_copy
($1);
874 * Rule 4: assignment -> un_op var;
876 | unary_operator variable sySEMICOLON
880 yyerror ("[Clan] Error: changing value of iterator/parameter");
884 $$
[1] = scoplib_matrix_copy
($2);
887 * Rule 5: assignment -> var;
889 | variable sySEMICOLON
895 * Rule 5: assignment -> { assignment };
897 | syRBRACE assignment syLBRACE
906 * Shortcut rules for all binary operators BUT '='.
926 * Rules for an expression.
931 * Rule 1: expression -> number
938 * Rule 2: expression -> - number
945 * Rule 3: expression -> variable
952 * Rule 4: expression -> expression bin_op expression
953 * The %prec is a hack to force to shift in this rule.
955 | expression binary_operator expression %prec MAXPRIORITY
957 $$
= scoplib_matrix_concat
($1,$3);
958 scoplib_matrix_free
($1);
959 scoplib_matrix_free
($3);
962 * Rule 5: expression -> ! expression
969 * Rule 6: expression -> ( expression )
971 | syRPARENTHESIS expression syLPARENTHESIS
976 * Rule 7: expression -> expression : expression ? expression
978 | expression opQMARK expression opCOLON expression
980 scoplib_matrix_p tmp
= scoplib_matrix_concat
($1,$3);
981 $$
= scoplib_matrix_concat
(tmp
,$5);
982 scoplib_matrix_free
(tmp
);
983 scoplib_matrix_free
($1);
984 scoplib_matrix_free
($3);
985 scoplib_matrix_free
($5);
991 * Rules to describe a variable. It can be a scalar ('a'), a
992 * n-dimensional array ('a[i]'), or a procedure call ('a(b,c,d)')
997 * Rule 1: variable -> id
1003 scoplib_matrix_p matrix
;
1004 char* s
= (char*) $1;
1005 clan_symbol_p symbol
= clan_symbol_lookup
(parser_symbol
, s
);
1006 // If the variable is an iterator or a parameter, discard it
1007 // from the read/write clause.
1008 if
((symbol
&& symbol
->type
== SCOPLIB_TYPE_ITERATOR
) ||
1009 (symbol
&& symbol
->type
== SCOPLIB_TYPE_PARAMETER
))
1013 clan_symbol_add
(&parser_symbol
, s
, SCOPLIB_TYPE_ARRAY
,parser_depth
);
1014 rank
= clan_symbol_get_rank
(parser_symbol
, s
);
1015 matrix
= scoplib_matrix_malloc
1016 (1, CLAN_MAX_DEPTH
+ CLAN_MAX_PARAMETERS
+ 2);
1017 clan_matrix_tag_array
(matrix
, rank
);
1023 * Rule 2: variable -> id array_index
1024 * ex: variable -> a[i][j]
1029 clan_symbol_add
(&parser_symbol
,$1,SCOPLIB_TYPE_ARRAY
,parser_depth
);
1030 rank
= clan_symbol_get_rank
(parser_symbol
,$1);
1031 clan_matrix_tag_array
($2,rank
);
1036 * Rule 3: variable -> id ( variable_list )
1037 * ex: variable -> a(b,c,d)
1039 | id syRPARENTHESIS variable_list syLPARENTHESIS
1045 * Rule 4: variable -> - variable
1052 * Rule 5: variable -> + variable
1062 * Dummy rule for basic arithmetic expression. Used in variable_list.
1064 arithmetic_expression:
1066 | arithmetic_expression opMINUS arithmetic_expression
1067 | arithmetic_expression opPLUS arithmetic_expression
1068 | arithmetic_expression opMULTIPLY arithmetic_expression
1069 | arithmetic_expression opDIVIDE arithmetic_expression
1070 | syRPARENTHESIS arithmetic_expression syLPARENTHESIS
1075 * Rules to describe a list of variables, separated by a comma.
1080 * Rule 1: variable_list -> variable
1087 * Rule 2: variable_list -> variable_list , variable
1089 | variable_list syCOMMA variable
1091 $$
= scoplib_matrix_concat
($1,$3);
1094 * Rule 3: variable_list -> variable_list , arithmetic_expression
1096 | variable_list syCOMMA arithmetic_expression
1101 * Rule 3: variable_list -> arithmetic_expression, variable_list
1103 | arithmetic_expression
1108 * Rule 3: variable_list ->
1118 * Rules for n-level array indices
1124 * Rule 1: array_index -> [ <affex> ]
1126 syRBRACKET affine_expression syLBRACKET
1128 $$
= scoplib_matrix_from_vector
($2);
1129 scoplib_vector_free
($2);
1132 * Rule 2: array_index -> array_index [ <affex> ]
1134 | array_index syRBRACKET affine_expression syLBRACKET
1137 scoplib_matrix_insert_vector
($1,$3,$1->NbRows
);
1138 scoplib_vector_free
($3);
1145 * Rules to (1) eliminate the parenthesis around an identifier, and
1146 * (2) support the &ID reference operator
1160 * Rule 2: id -> ( ID )
1162 | syRPARENTHESIS ID syLPARENTHESIS
1167 * Rule 3: id -> & ID
1174 * Rule 4: id -> math_func_list
1182 math_func_list: MIN | MAX | CEILD | FLOORD
;
1195 fprintf
(stderr
, "%s\n", s
);
1196 clan_parse_error
= 1;
1201 * clan_parser_initialize_state function:
1202 * this function achieves the initialization of the "parser state": a
1203 * collection of variables that vary during the parsing and thanks to we
1204 * can extract all SCoP informations.
1206 * - 02/05/2008: First version.
1209 clan_parser_initialize_state
(clan_options_p options
)
1211 int i
, nb_rows
, nb_columns
, depth
;
1213 nb_rows
= CLAN_MAX_CONSTRAINTS
;
1214 nb_columns
= CLAN_MAX_DEPTH
+ CLAN_MAX_PARAMETERS
+ 2;
1215 depth
= CLAN_MAX_DEPTH
;
1217 parser_scop
= scoplib_scop_malloc
();
1218 parser_domain
= scoplib_matrix_malloc
(nb_rows
,nb_columns
);
1219 parser_symbol
= NULL
;
1221 parser_scheduling
= (int *)malloc
(depth
* sizeof
(int));
1222 parser_consperdim
= (int *)malloc
(depth
* sizeof
(int));
1223 for
(i
= 0; i
< depth
; i
++)
1225 parser_scheduling
[i
] = 0;
1226 parser_consperdim
[i
] = 0;
1228 parser_iterators
= (clan_symbol_p
*)malloc
(depth
* sizeof
(clan_symbol_p
));
1229 parser_variables_localvars
=
1230 (int*)malloc
((CLAN_MAX_LOCAL_VARIABLES
+ 1) * sizeof
(int));
1231 parser_variables_liveout
=
1232 (int*)malloc
((CLAN_MAX_LOCAL_VARIABLES
+ 1) * sizeof
(int));
1235 /* Reset also the Symbol global variables. */
1236 extern
int symbol_nb_iterators
;
1237 symbol_nb_iterators
= 0;
1238 extern
int symbol_nb_parameters
;
1239 symbol_nb_parameters
= 0;
1240 extern
int symbol_nb_arrays
;
1241 symbol_nb_arrays
= 0;
1242 extern
int symbol_nb_functions
;
1243 symbol_nb_functions
= 0;
1245 for
(i
= 0; i
<= CLAN_MAX_LOCAL_VARIABLES
; ++i
)
1246 parser_variables_localvars
[i
] = -1;
1247 for
(i
= 0; i
<= CLAN_MAX_LOCAL_VARIABLES
; ++i
)
1248 parser_variables_liveout
[i
] = -1;
1250 parser_options
= options
;
1254 * clan_parser_free_state function:
1255 * this function frees the memory allocated for the "parser state", except
1256 * for parser_scop, obviously.
1258 * - 02/05/2008: First version.
1261 clan_parser_free_state
()
1263 scoplib_matrix_free
(parser_domain
);
1264 clan_symbol_free
(parser_symbol
);
1265 free
(parser_scheduling
);
1266 free
(parser_consperdim
);
1267 free
(parser_iterators
);
1268 free
(parser_variables_localvars
);
1269 free
(parser_variables_liveout
);
1273 * clan_parse function:
1274 * this function parses a file to extract a SCoP and returns, if successful,
1275 * a pointer to the scoplib_scop_t structure.
1276 * \param input The file to parse (already open).
1277 * \param options Options for file parsing.
1279 * - 01/05/2008: First version.
1282 clan_parse
(FILE * input
, clan_options_p options
)
1286 clan_parser_initialize_state
(options
);
1291 if
(! clan_parse_error
)
1293 if
(parser_variables_localvars
[0] != -1 ||
1294 parser_variables_liveout
[0] != -1)
1295 clan_scop_fill_options
(parser_scop
, parser_variables_localvars
,
1296 parser_variables_liveout
);
1297 clan_scop_compact
(parser_scop
);
1301 clan_parser_free_state
();