initial version of ppcg
[ppcg.git] / clan / source / parser.y
blob49b32f4e20fb07a1953eeb34d1a560605ebab7b8
2 /*+------- <| --------------------------------------------------------**
3 ** A Clan **
4 **--- /.\ -----------------------------------------------------**
5 ** <| [""M# parser.y **
6 **- A | # -----------------------------------------------------**
7 ** /.\ [""M# First version: 30/04/2008 **
8 **- [""M# | # U"U#U -----------------------------------------------**
9 | # | # \ .:/
10 | # | #___| #
11 ****** | "--' .-" ******************************************************
12 * |"-"-"-"-"-#-#-## Clan : the Chunky Loop Analyzer (experimental) *
13 **** | # ## ###### *****************************************************
14 * \ .::::'/ *
15 * \ ::::'/ Copyright (C) 2008 Cedric Bastoul *
16 * :8a| # # ## *
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 *
27 * for more details. *
28 * *
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 *
32 * *
33 * Clan, the Chunky Loop Analyzer *
34 * Written by Cedric Bastoul, Cedric.Bastoul@inria.fr *
35 * *
36 ******************************************************************************/
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <assert.h>
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>
52 int yylex(void);
53 void yyerror(char *);
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
70 (statement body) */
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
77 dimension */
78 int* parser_variables_localvars;/**< List of variables
79 in #pragma
80 local-vars */
81 int* parser_variables_liveout;/**< List of variables
82 in #pragma
83 live-out */
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 */
97 %token IGNORE
98 %token IF ELSE FOR PRAGMALOCALVARS PRAGMALIVEOUT
99 %token MIN MAX CEILD FLOORD
100 %token REAL
101 %token <symbol> ID
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
110 %token opASSIGNMENT
111 %token opPLUSEQUAL opMINUSEQUAL opMULTIPLYEQUAL opDIVIDEEQUAL
112 %token opMODEQUAL opANDEQUAL opOREQUAL opCOMPEQUAL
113 %token opLAND opLOR opQMARK opCOLON
115 %left opPLUS opMINUS
116 %left opMULTIPLY opDIVIDE opMOD opAND opOR opCOMP
117 %left opEQUAL opLEQ opGEQ opLOWER opGREATER opLAND opCOLON opQMARK
118 %left opNOT
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
125 %type <affex> term
126 %type <setex> array_index
127 %type <setex> variable
128 %type <setex> variable_list
129 %type <setex> expression
130 %type <rw> assignment
131 %type <symbol> id
136 * Start rule.
139 program:
140 instruction_list
142 /* The full program was parsed. Allocate and fill the final
143 .scop structures. */
144 int nb_parameters, nb_arrays;
146 parser_scop->parameters = clan_symbol_id_array(parser_symbol,
147 SCOPLIB_TYPE_PARAMETER,
148 &nb_parameters);
149 parser_scop->nb_parameters = nb_parameters;
150 parser_scop->arrays = clan_symbol_id_array(parser_symbol,
151 SCOPLIB_TYPE_ARRAY,
152 &nb_arrays);
153 parser_scop->nb_arrays = nb_arrays;
154 if (parser_options->bounded_context)
156 parser_scop->context = scoplib_matrix_malloc(nb_parameters,
157 nb_parameters+2);
158 int i;
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);
166 else
167 parser_scop->context = scoplib_matrix_malloc(0,nb_parameters+2);
173 * Rules for a list of instructions
176 instruction_list:
177 instruction
178 | instruction_list instruction
179 | IGNORE
180 | instruction_list IGNORE
181 | syRBRACE instruction_list syLBRACE
186 * Rules for a bloc of instructions.
188 bloc:
190 * Rule 1: bloc -> instruction
192 instruction
194 * Rule 2: bloc -> { instruction_list }
196 | syRBRACE instruction_list syLBRACE
201 * Rules for a program instruction. Either a for(..., if(..., or a
202 * regular statement.
205 instruction:
207 * Rule 1: instruction -> for ( id = <setex>; condition; increment) bloc
211 syRPARENTHESIS
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"
223 "\n");
224 return 0;
226 /* Update the rank, in case a symbol with the same name was
227 already existing. */
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 */
233 opASSIGNMENT
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);
238 int i, j;
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);
250 free($3);
251 scoplib_matrix_free($6);
253 sySEMICOLON
254 condition
256 scoplib_matrix_insert_matrix(parser_domain,$9,parser_nb_cons);
257 parser_nb_cons += $9->NbRows;
258 parser_consperdim[parser_depth] += $9->NbRows;
260 sySEMICOLON
261 incrementation
262 syLPARENTHESIS
264 parser_depth++;
265 parser_scheduling[parser_depth] = 0;
267 bloc
269 parser_depth--;
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;
285 bloc
287 parser_nb_cons -= $3->NbRows;
288 /* Remove the condition constraint from the current parser domain. */
289 int i, j;
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);
308 assignment
310 /* Deal with statements without surrounding loop by adding a
311 fake iterator */
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);
317 if (symbol)
318 free(fakeiter);
319 else
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);
326 parser_depth++;
327 scoplib_matrix_replace_vector(parser_domain,constraint,parser_nb_cons);
328 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,
334 parser_nb_cons);
335 parser_statement->schedule = clan_matrix_scheduling(parser_scheduling,
336 parser_depth);
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,
342 parser_depth);
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
352 original state */
353 if (old_parser_depth == 0)
355 --parser_depth;
356 --parser_nb_cons;
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
368 int i, j;
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");
379 return 0;
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
392 int i, j;
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");
403 return 0;
405 if (parser_variables_liveout[j] == -1)
406 parser_variables_liveout[j] = id;
413 * Rules for the for loop increment.
414 * Handled cases:
415 * i++, ++i, i = i + 1, i += 1
418 incrementation:
419 id opINCREMENTATION
421 free($1);
423 | opINCREMENTATION id
425 free($2);
427 | id opASSIGNMENT id opPLUS INTEGER
429 if ($5 != 1)
431 yyerror("[Clan] Error: loop increment is not 1\n");
432 return 0;
434 free ($1);
435 free ($3);
437 | id opPLUSEQUAL INTEGER
439 if ($3 != 1)
441 yyerror("[Clan] Error: loop increment is not 1\n");
442 return 0;
444 free ($1);
450 * Reduction rules for min(... operators.
451 * return <setex>
454 min_affine_expression:
455 affine_expression
457 $$ = scoplib_matrix_from_vector($1);
458 scoplib_vector_free($1);
460 | MIN syRPARENTHESIS min_affine_expression syCOMMA min_affine_expression
461 syLPARENTHESIS
463 $$ = scoplib_matrix_concat($3, $5);
469 * Reduction rules for max(... operators.
470 * return <setex>
473 max_affine_expression:
474 affine_expression
476 $$ = scoplib_matrix_from_vector($1);
477 scoplib_vector_free($1);
479 | MAX syRPARENTHESIS max_affine_expression syCOMMA max_affine_expression
480 syLPARENTHESIS
482 $$ = scoplib_matrix_concat($3, $5);
488 * Reduction rules for affine expression.
489 * return <affex>
492 affine_expression:
493 term
495 $$ = $1;
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
511 $$ = $2;
513 | CEILD syRPARENTHESIS affine_expression syCOMMA term syLPARENTHESIS
515 SCOPVAL_assign($3->p[0], $5->p[$5->Size - 1]);
516 $$ = $3;
518 | FLOORD syRPARENTHESIS affine_expression syCOMMA term syLPARENTHESIS
520 SCOPVAL_assign($3->p[0], $5->p[$5->Size - 1]);
521 $$ = $3;
527 * Reduction rules for a term.
528 * return <affex>
531 term:
533 * Rule 1: term -> INT
535 INTEGER
537 $$ = clan_vector_term(parser_symbol,$1,NULL);
540 * Rule 2: term -> id
542 | id
544 clan_symbol_add(&parser_symbol,$1,SCOPLIB_TYPE_UNKNOWN,parser_depth);
545 $$ = clan_vector_term(parser_symbol,1,$1);
546 free($1);
549 * Rule 3: term -> - INT
551 | opMINUS INTEGER
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);
562 free($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);
571 free($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);
594 free($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);
603 free($2);
606 * Rule 8: term -> - id
608 | opMINUS id
610 clan_symbol_add(&parser_symbol,$2,SCOPLIB_TYPE_UNKNOWN,parser_depth);
611 $$ = clan_vector_term(parser_symbol,-1,$2);
612 free($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 '>='.
622 * return: <setex>
624 condition:
626 * Rule 1: condition -> <affex> < min_affex
628 affine_expression opLOWER min_affine_expression
630 /* a<b translates to -a+b-1>=0 */
631 int i;
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);
643 int j;
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);
651 SCOPVAL_clear(val);
653 else
654 scoplib_matrix_sub_vector($3, tmp, i);
656 scoplib_vector_free($1);
657 scoplib_vector_free(tmp);
658 $$ = $3;
661 * Rule 2: condition -> <affex> > max_affex
663 | affine_expression opGREATER max_affine_expression
665 /* a>b translates to a-b-1>=0 */
666 int i, j;
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);
680 int j;
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);
688 SCOPVAL_clear(val);
690 else
691 scoplib_matrix_add_vector($3,tmp,i);
693 scoplib_vector_free($1);
694 scoplib_vector_free(tmp);
695 $$ = $3;
698 * Rule 3: condition -> <affex> <= min_affex
700 | affine_expression opLEQ min_affine_expression
702 /* a<=b translates to -a+b>=0 */
703 int i;
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);
715 int j;
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);
721 SCOPVAL_clear(val);
723 else
724 scoplib_matrix_sub_vector($3,tmp,i);
726 scoplib_vector_free($1);
727 scoplib_vector_free(tmp);
728 $$ = $3;
731 * Rule 4: condition -> <affex> >= max_affex
733 | affine_expression opGEQ max_affine_expression
735 /* a>=b translates to a-b>=0 */
736 int i, j;
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);
750 int j;
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);
756 SCOPVAL_clear(val);
758 else
759 scoplib_matrix_add_vector($3,tmp,i);
761 scoplib_vector_free($1);
762 scoplib_vector_free(tmp);
763 $$ = $3;
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
787 $$ = $2;
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 (+=, -=, ...)
805 reduction_operator:
806 opPLUSEQUAL
807 | opMINUSEQUAL
808 | opMULTIPLYEQUAL
809 | opDIVIDEEQUAL
810 | opMODEQUAL
811 | opANDEQUAL
812 | opOREQUAL
813 | opCOMPEQUAL
818 * Shortcut rules for unary increment/decrement operators (-- and ++)
821 unary_operator:
822 opINCREMENTATION
823 | opDECREMENTATION
828 * Rules for an assignment (an instruction which is not a 'for' nor an 'if')
829 * return: <rw>
832 assignment:
834 * Rule 1: assignment -> var = expression;
836 variable opASSIGNMENT expression sySEMICOLON
838 if ($1 == NULL)
840 yyerror ("[Clan] Error: changing value of iterator/parameter");
841 return 0;
843 $$[0] = $3;
844 $$[1] = $1;
847 * Rule 2: assignment -> var red_op expression;
849 | variable reduction_operator expression sySEMICOLON
851 if ($1 == NULL)
853 yyerror ("[Clan] Error: changing value of iterator/parameter");
854 return 0;
856 $$[0] = scoplib_matrix_concat($1,$3);
857 scoplib_matrix_free($3);
858 $$[1] = $1;
861 * Rule 3: assignment -> var un_op;
863 | variable unary_operator sySEMICOLON
865 if ($1 == NULL)
867 yyerror ("[Clan] Error: changing value of iterator/parameter");
868 return 0;
870 $$[0] = $1;
871 $$[1] = scoplib_matrix_copy($1);
874 * Rule 4: assignment -> un_op var;
876 | unary_operator variable sySEMICOLON
878 if ($2 == NULL)
880 yyerror ("[Clan] Error: changing value of iterator/parameter");
881 return 0;
883 $$[0] = $2;
884 $$[1] = scoplib_matrix_copy($2);
887 * Rule 5: assignment -> var;
889 | variable sySEMICOLON
891 $$[0] = $1;
892 $$[1] = NULL;
895 * Rule 5: assignment -> { assignment };
897 | syRBRACE assignment syLBRACE
899 $$[0] = $2[0];
900 $$[1] = $2[1];
906 * Shortcut rules for all binary operators BUT '='.
909 binary_operator:
910 opPLUS
911 | opMINUS
912 | opMULTIPLY
913 | opDIVIDE
914 | opMOD
915 | opGEQ
916 | opGREATER
917 | opLEQ
918 | opLOWER
919 | opEQUAL
920 | opAND
921 | opOR
922 | opCOMP
926 * Rules for an expression.
927 * return: <setex>
929 expression:
931 * Rule 1: expression -> number
933 NUMBER
935 $$ = NULL;
938 * Rule 2: expression -> - number
940 | opMINUS NUMBER
942 $$ = NULL;
945 * Rule 3: expression -> variable
947 | variable
949 $$ = $1;
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
964 | opNOT expression
966 $$ = $2;
969 * Rule 6: expression -> ( expression )
971 | syRPARENTHESIS expression syLPARENTHESIS
973 $$ = $2;
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)')
993 * return: <setex>
995 variable:
997 * Rule 1: variable -> id
998 * ex: variable -> a
1002 int rank;
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))
1010 $$ = NULL;
1011 else
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);
1018 $$ = matrix;
1020 free($1);
1023 * Rule 2: variable -> id array_index
1024 * ex: variable -> a[i][j]
1026 | id array_index
1028 int rank;
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);
1032 $$ = $2;
1033 free($1);
1036 * Rule 3: variable -> id ( variable_list )
1037 * ex: variable -> a(b,c,d)
1039 | id syRPARENTHESIS variable_list syLPARENTHESIS
1041 $$ = $3;
1042 free($1);
1045 * Rule 4: variable -> - variable
1047 | opMINUS variable
1049 $$ = $2;
1052 * Rule 5: variable -> + variable
1054 | opPLUS variable
1056 $$ = $2;
1062 * Dummy rule for basic arithmetic expression. Used in variable_list.
1064 arithmetic_expression:
1065 NUMBER
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.
1076 * return: <setex>
1078 variable_list:
1080 * Rule 1: variable_list -> variable
1082 variable
1084 $$ = $1;
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
1098 $$ = $1;
1101 * Rule 3: variable_list -> arithmetic_expression, variable_list
1103 | arithmetic_expression
1105 $$ = NULL;
1108 * Rule 3: variable_list ->
1112 $$ = NULL;
1118 * Rules for n-level array indices
1119 * return: <setex>
1122 array_index:
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
1136 if ($1 != NULL)
1137 scoplib_matrix_insert_vector($1,$3,$1->NbRows);
1138 scoplib_vector_free($3);
1139 $$ = $1;
1145 * Rules to (1) eliminate the parenthesis around an identifier, and
1146 * (2) support the &ID reference operator
1147 * operator.
1149 * return <symbol>
1153 * Rule 1: id -> ID
1157 $$ = $1;
1160 * Rule 2: id -> ( ID )
1162 | syRPARENTHESIS ID syLPARENTHESIS
1164 $$ = $2;
1167 * Rule 3: id -> & ID
1169 | opAND ID
1171 $$ = $2;
1174 * Rule 4: id -> math_func_list
1176 | math_func_list
1178 $$ = NULL;
1182 math_func_list: MIN | MAX | CEILD | FLOORD;
1184 NUMBER:
1185 INTEGER
1186 | REAL
1192 void
1193 yyerror(char *s)
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.
1208 void
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));
1233 parser_depth = 0;
1234 parser_nb_cons = 0;
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.
1260 void
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.
1281 scoplib_scop_p
1282 clan_parse(FILE * input, clan_options_p options)
1284 yyin = input;
1286 clan_parser_initialize_state(options);
1288 yyparse();
1290 fclose(yyin);
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);
1299 else
1300 parser_scop = NULL;
1301 clan_parser_free_state();
1303 return parser_scop;