4 #include "isl_map_private.h"
5 #include "isl_input_omega.h"
7 enum token_type { TOKEN_UNKNOWN = 256, TOKEN_VALUE, TOKEN_IDENT, TOKEN_GE,
8 TOKEN_LE, TOKEN_TO, TOKEN_AND, TOKEN_EXISTS };
13 unsigned int on_new_line : 1;
23 static struct token *token_new(struct isl_ctx *ctx,
24 int line, int col, unsigned on_new_line)
26 struct token *tok = isl_alloc_type(ctx, struct token);
31 tok->on_new_line = on_new_line;
35 void token_free(struct token *tok)
39 if (tok->type == TOKEN_VALUE)
40 isl_int_clear(tok->u.v);
41 else if (tok->type == TOKEN_IDENT)
59 struct token *tokens[5];
63 void stream_error(struct stream *s, struct token *tok, char *msg)
65 int line = tok ? tok->line : s->line;
66 int col = tok ? tok->col : s->col;
67 fprintf(stderr, "syntax error (%d, %d): %s\n", line, col, msg);
70 fprintf(stderr, "got '%c'\n", tok->type);
72 fprintf(stderr, "got token type %d\n", tok->type);
76 static void stream_free(struct stream *s);
78 static struct stream* stream_new(struct isl_ctx *ctx)
81 struct stream *s = isl_alloc_type(ctx, struct stream);
88 s->buffer = isl_alloc_array(ctx, char, s->size);
96 for (i = 0; i < 5; ++i)
105 static struct stream* stream_new_file(struct isl_ctx *ctx, FILE *file)
107 struct stream *s = stream_new(ctx);
114 static int stream_getc(struct stream *s)
139 static void stream_ungetc(struct stream *s, int c)
148 static int stream_push_char(struct stream *s, int c)
150 if (s->len >= s->size) {
151 s->size = (3*s->size)/2;
152 s->buffer = isl_realloc_array(ctx, s->buffer, char, s->size);
156 s->buffer[s->len++] = c;
160 static void stream_push_token(struct stream *s, struct token *tok)
162 isl_assert(s->ctx, s->n_token < 5, return);
163 s->tokens[s->n_token++] = tok;
166 static struct token *stream_next_token(struct stream *s)
169 struct token *tok = NULL;
171 int old_line = s->line;
174 return s->tokens[--s->n_token];
179 while ((c = stream_getc(s)) != -1 && isspace(c))
201 tok = token_new(s->ctx, line, col, old_line != line);
204 tok->type = (enum token_type)c;
209 if ((c = stream_getc(s)) == '>') {
210 tok = token_new(s->ctx, line, col, old_line != line);
213 tok->type = TOKEN_TO;
219 if (c == '-' || isdigit(c)) {
220 tok = token_new(s->ctx, line, col, old_line != line);
223 tok->type = TOKEN_VALUE;
224 isl_int_init(tok->u.v);
225 if (stream_push_char(s, c))
227 while ((c = stream_getc(s)) != -1 && isdigit(c))
228 if (stream_push_char(s, c))
232 if (s->len == 1 && s->buffer[0] == '-')
233 isl_int_set_si(tok->u.v, -1);
235 stream_push_char(s, '\0');
236 isl_int_read(tok->u.v, s->buffer);
241 tok = token_new(s->ctx, line, col, old_line != line);
244 stream_push_char(s, c);
245 while ((c = stream_getc(s)) != -1 && isalnum(c))
246 stream_push_char(s, c);
249 stream_push_char(s, '\0');
250 if (!strcasecmp(s->buffer, "exists"))
251 tok->type = TOKEN_EXISTS;
253 tok->type = TOKEN_IDENT;
254 tok->u.s = strdup(s->buffer);
260 if ((c = stream_getc(s)) == '=') {
261 tok = token_new(s->ctx, line, col, old_line != line);
264 tok->type = TOKEN_GE;
272 if ((c = stream_getc(s)) == '=') {
273 tok = token_new(s->ctx, line, col, old_line != line);
276 tok->type = TOKEN_LE;
283 tok = token_new(s->ctx, line, col, old_line != line);
286 tok->type = TOKEN_AND;
287 if ((c = stream_getc(s)) != '&' && c != -1)
292 tok = token_new(s->ctx, line, col, old_line != line);
295 tok->type = TOKEN_UNKNOWN;
302 static int stream_eat(struct stream *s, int type)
306 tok = stream_next_token(s);
309 if (tok->type == type) {
313 stream_error(s, tok, "expecting other token");
314 stream_push_token(s, tok);
318 static void stream_free(struct stream *s)
323 if (s->n_token != 0) {
324 struct token *tok = stream_next_token(s);
325 stream_error(s, tok, "unexpected token");
334 struct variable *next;
343 static struct vars *vars_new(struct isl_ctx *ctx)
346 v = isl_alloc_type(ctx, struct vars);
355 void variable_free(struct variable *var)
358 struct variable *next = var->next;
365 static void vars_free(struct vars *v)
373 struct variable *variable_new(struct vars *v, const char *name, int len,
376 struct variable *var;
377 var = isl_alloc_type(v->ctx, struct variable);
380 var->name = strdup(name);
381 var->name[len] = '\0';
390 static int vars_pos(struct vars *v, const char *s, int len)
397 for (q = v->v; q; q = q->next) {
398 if (strncmp(q->name, s, len) == 0 && q->name[len] == '\0')
405 v->v = variable_new(v, s, len, v->n);
413 static struct vars *read_var_list(struct stream *s, struct vars *v)
417 while ((tok = stream_next_token(s)) != NULL) {
421 if (tok->type != TOKEN_IDENT)
424 p = vars_pos(v, tok->u.s, -1);
428 stream_error(s, tok, "expecting unique identifier");
432 tok = stream_next_token(s);
433 if (!tok || tok->type != ',')
439 stream_push_token(s, tok);
448 static struct vars *read_tuple(struct stream *s, struct vars *v)
452 tok = stream_next_token(s);
453 if (!tok || tok->type != '[') {
454 stream_error(s, tok, "expecting '['");
458 v = read_var_list(s, v);
459 tok = stream_next_token(s);
460 if (!tok || tok->type != ']') {
461 stream_error(s, tok, "expecting ']'");
474 static struct isl_basic_map *add_constraints(struct stream *s,
475 struct vars **v, struct isl_basic_map *bmap);
477 static struct isl_basic_map *add_exists(struct stream *s,
478 struct vars **v, struct isl_basic_map *bmap)
487 tok = stream_next_token(s);
490 if (tok->type == '(') {
494 stream_push_token(s, tok);
495 *v = read_var_list(s, *v);
499 bmap = isl_basic_map_extend(bmap, bmap->nparam,
500 bmap->n_in, bmap->n_out, extra, 0, 0);
501 total = bmap->nparam+bmap->n_in+bmap->n_out+bmap->extra;
502 for (i = 0; i < extra; ++i) {
504 if ((k = isl_basic_map_alloc_div(bmap)) < 0)
506 isl_seq_clr(bmap->div[k], 1+1+total);
510 if (stream_eat(s, ':'))
512 bmap = add_constraints(s, v, bmap);
513 if (seen_paren && stream_eat(s, ')'))
517 isl_basic_map_free(bmap);
521 static struct isl_basic_map *add_constraint(struct stream *s,
522 struct vars **v, struct isl_basic_map *bmap)
524 unsigned total = bmap->nparam+bmap->n_in+bmap->n_out+bmap->extra;
529 struct token *tok = NULL;
531 tok = stream_next_token(s);
534 if (tok->type == TOKEN_EXISTS) {
536 return add_exists(s, v, bmap);
538 stream_push_token(s, tok);
540 bmap = isl_basic_map_extend(bmap, bmap->nparam,
541 bmap->n_in, bmap->n_out, 0, 0, 1);
542 k = isl_basic_map_alloc_inequality(bmap);
545 isl_seq_clr(bmap->ineq[k], 1+total);
548 tok = stream_next_token(s);
550 stream_error(s, NULL, "unexpected EOF");
553 if (tok->type == TOKEN_IDENT) {
555 int pos = vars_pos(*v, tok->u.s, -1);
559 stream_error(s, tok, "unknown identifier");
563 isl_int_add_ui(bmap->ineq[k][1+pos],
564 bmap->ineq[k][1+pos], 1);
566 isl_int_sub_ui(bmap->ineq[k][1+pos],
567 bmap->ineq[k][1+pos], 1);
568 } else if (tok->type == TOKEN_VALUE) {
572 tok2 = stream_next_token(s);
573 if (tok2 && tok2->type == TOKEN_IDENT) {
574 pos = vars_pos(*v, tok2->u.s, -1);
578 stream_error(s, tok2,
579 "unknown identifier");
585 stream_push_token(s, tok2);
587 isl_int_neg(tok->u.v, tok->u.v);
588 isl_int_add(bmap->ineq[k][1+pos],
589 bmap->ineq[k][1+pos], tok->u.v);
590 } else if (tok->type == TOKEN_LE) {
592 isl_seq_neg(bmap->ineq[k], bmap->ineq[k], 1+total);
593 } else if (tok->type == TOKEN_GE) {
596 } else if (tok->type == '=') {
598 stream_error(s, tok, "too many operators");
605 stream_push_token(s, tok);
612 stream_error(s, tok, "missing operator");
616 isl_basic_map_inequality_to_equality(bmap, k);
621 isl_basic_map_free(bmap);
625 static struct isl_basic_map *add_constraints(struct stream *s,
626 struct vars **v, struct isl_basic_map *bmap)
631 bmap = add_constraint(s, v, bmap);
634 tok = stream_next_token(s);
636 stream_error(s, NULL, "unexpected EOF");
639 if (tok->type != TOKEN_AND)
643 stream_push_token(s, tok);
649 isl_basic_map_free(bmap);
653 static struct isl_basic_map *basic_map_read(struct stream *s)
655 struct isl_basic_map *bmap = NULL;
657 struct vars *v = NULL;
661 tok = stream_next_token(s);
662 if (!tok || tok->type != '{') {
663 stream_error(s, tok, "expecting '{'");
665 stream_push_token(s, tok);
669 v = vars_new(s->ctx);
670 v = read_tuple(s, v);
674 tok = stream_next_token(s);
675 if (tok && tok->type == TOKEN_TO) {
677 v = read_tuple(s, v);
683 stream_push_token(s, tok);
687 bmap = isl_basic_map_alloc(s->ctx, 0, n1, n2, 0, 0,0);
690 tok = stream_next_token(s);
691 if (tok && tok->type == ':') {
693 bmap = add_constraints(s, &v, bmap);
694 tok = stream_next_token(s);
696 if (tok && tok->type == '}') {
699 stream_error(s, tok, "unexpected token");
708 isl_basic_map_free(bmap);
714 struct isl_basic_map *isl_basic_map_read_from_file_omega(
715 struct isl_ctx *ctx, FILE *input)
717 struct isl_basic_map *bmap;
718 struct stream *s = stream_new_file(ctx, input);
721 bmap = basic_map_read(s);
726 struct isl_basic_set *isl_basic_set_read_from_file_omega(
727 struct isl_ctx *ctx, FILE *input)
729 struct isl_basic_map *bmap;
730 bmap = isl_basic_map_read_from_file_omega(ctx, input);
733 isl_assert(ctx, bmap->n_in == 0, goto error);
734 return (struct isl_basic_set *)bmap;
736 isl_basic_map_free(bmap);