4 #include "isl_input_omega.h"
6 enum token_type { TOKEN_UNKNOWN = 256, TOKEN_VALUE, TOKEN_IDENT, TOKEN_GE,
7 TOKEN_LE, TOKEN_TO, TOKEN_AND, TOKEN_EXISTS };
12 unsigned int on_new_line : 1;
22 static struct token *token_new(struct isl_ctx *ctx,
23 int line, int col, unsigned on_new_line)
25 struct token *tok = isl_alloc_type(ctx, struct token);
30 tok->on_new_line = on_new_line;
34 void token_free(struct token *tok)
38 if (tok->type == TOKEN_VALUE)
39 isl_int_clear(tok->u.v);
40 else if (tok->type == TOKEN_IDENT)
58 struct token *tokens[5];
62 void stream_error(struct stream *s, struct token *tok, char *msg)
64 int line = tok ? tok->line : s->line;
65 int col = tok ? tok->col : s->col;
66 fprintf(stderr, "syntax error (%d, %d): %s\n", line, col, msg);
69 fprintf(stderr, "got '%c'\n", tok->type);
71 fprintf(stderr, "got token type %d\n", tok->type);
75 static void stream_free(struct stream *s);
77 static struct stream* stream_new(struct isl_ctx *ctx)
80 struct stream *s = isl_alloc_type(ctx, struct stream);
87 s->buffer = isl_alloc_array(ctx, char, s->size);
95 for (i = 0; i < 5; ++i)
104 static struct stream* stream_new_file(struct isl_ctx *ctx, FILE *file)
106 struct stream *s = stream_new(ctx);
113 static int stream_getc(struct stream *s)
138 static void stream_ungetc(struct stream *s, int c)
147 static int stream_push_char(struct stream *s, int c)
149 if (s->len >= s->size) {
150 s->size = (3*s->size)/2;
151 s->buffer = isl_realloc_array(ctx, s->buffer, char, s->size);
155 s->buffer[s->len++] = c;
159 static void stream_push_token(struct stream *s, struct token *tok)
161 isl_assert(s->ctx, s->n_token < 5, return);
162 s->tokens[s->n_token++] = tok;
165 static struct token *stream_next_token(struct stream *s)
168 struct token *tok = NULL;
170 int old_line = s->line;
173 return s->tokens[--s->n_token];
178 while ((c = stream_getc(s)) != -1 && isspace(c))
200 tok = token_new(s->ctx, line, col, old_line != line);
203 tok->type = (enum token_type)c;
208 if ((c = stream_getc(s)) == '>') {
209 tok = token_new(s->ctx, line, col, old_line != line);
212 tok->type = TOKEN_TO;
218 if (c == '-' || isdigit(c)) {
219 tok = token_new(s->ctx, line, col, old_line != line);
222 tok->type = TOKEN_VALUE;
223 isl_int_init(tok->u.v);
224 if (stream_push_char(s, c))
226 while ((c = stream_getc(s)) != -1 && isdigit(c))
227 if (stream_push_char(s, c))
231 if (s->len == 1 && s->buffer[0] == '-')
232 isl_int_set_si(tok->u.v, -1);
234 stream_push_char(s, '\0');
235 isl_int_read(tok->u.v, s->buffer);
240 tok = token_new(s->ctx, line, col, old_line != line);
243 stream_push_char(s, c);
244 while ((c = stream_getc(s)) != -1 && isalnum(c))
245 stream_push_char(s, c);
248 stream_push_char(s, '\0');
249 if (!strcasecmp(s->buffer, "exists"))
250 tok->type = TOKEN_EXISTS;
252 tok->type = TOKEN_IDENT;
253 tok->u.s = strdup(s->buffer);
259 if ((c = stream_getc(s)) == '=') {
260 tok = token_new(s->ctx, line, col, old_line != line);
263 tok->type = TOKEN_GE;
271 if ((c = stream_getc(s)) == '=') {
272 tok = token_new(s->ctx, line, col, old_line != line);
275 tok->type = TOKEN_LE;
282 tok = token_new(s->ctx, line, col, old_line != line);
285 tok->type = TOKEN_AND;
286 if ((c = stream_getc(s)) != '&' && c != -1)
291 tok = token_new(s->ctx, line, col, old_line != line);
294 tok->type = TOKEN_UNKNOWN;
301 static int stream_eat(struct stream *s, int type)
305 tok = stream_next_token(s);
308 if (tok->type == type) {
312 stream_error(s, tok, "expecting other token");
313 stream_push_token(s, tok);
317 static void stream_free(struct stream *s)
322 if (s->n_token != 0) {
323 struct token *tok = stream_next_token(s);
324 stream_error(s, tok, "unexpected token");
333 struct variable *next;
342 static struct vars *vars_new(struct isl_ctx *ctx)
345 v = isl_alloc_type(ctx, struct vars);
354 void variable_free(struct variable *var)
357 struct variable *next = var->next;
364 static void vars_free(struct vars *v)
372 struct variable *variable_new(struct vars *v, const char *name, int len,
375 struct variable *var;
376 var = isl_alloc_type(v->ctx, struct variable);
379 var->name = strdup(name);
380 var->name[len] = '\0';
389 static int vars_pos(struct vars *v, const char *s, int len)
396 for (q = v->v; q; q = q->next) {
397 if (strncmp(q->name, s, len) == 0 && q->name[len] == '\0')
404 v->v = variable_new(v, s, len, v->n);
412 static struct vars *read_var_list(struct stream *s, struct vars *v)
416 while ((tok = stream_next_token(s)) != NULL) {
420 if (tok->type != TOKEN_IDENT)
423 p = vars_pos(v, tok->u.s, -1);
427 stream_error(s, tok, "expecting unique identifier");
431 tok = stream_next_token(s);
432 if (!tok || tok->type != ',')
438 stream_push_token(s, tok);
447 static struct vars *read_tuple(struct stream *s, struct vars *v)
451 tok = stream_next_token(s);
452 if (!tok || tok->type != '[') {
453 stream_error(s, tok, "expecting '['");
457 v = read_var_list(s, v);
458 tok = stream_next_token(s);
459 if (!tok || tok->type != ']') {
460 stream_error(s, tok, "expecting ']'");
473 static struct isl_basic_map *add_constraints(struct stream *s,
474 struct vars **v, struct isl_basic_map *bmap);
476 static struct isl_basic_map *add_exists(struct stream *s,
477 struct vars **v, struct isl_basic_map *bmap)
486 tok = stream_next_token(s);
489 if (tok->type == '(') {
493 stream_push_token(s, tok);
494 *v = read_var_list(s, *v);
498 bmap = isl_basic_map_extend(s->ctx, bmap, bmap->nparam,
499 bmap->n_in, bmap->n_out, extra, 0, 0);
500 total = bmap->nparam+bmap->n_in+bmap->n_out+bmap->extra;
501 for (i = 0; i < extra; ++i) {
503 if ((k = isl_basic_map_alloc_div(s->ctx, bmap)) < 0)
505 isl_seq_clr(bmap->div[k], 1+1+total);
509 if (stream_eat(s, ':'))
511 bmap = add_constraints(s, v, bmap);
512 if (seen_paren && stream_eat(s, ')'))
516 isl_basic_map_free(s->ctx, bmap);
520 static struct isl_basic_map *add_constraint(struct stream *s,
521 struct vars **v, struct isl_basic_map *bmap)
523 unsigned total = bmap->nparam+bmap->n_in+bmap->n_out+bmap->extra;
528 struct token *tok = NULL;
530 tok = stream_next_token(s);
533 if (tok->type == TOKEN_EXISTS) {
535 return add_exists(s, v, bmap);
537 stream_push_token(s, tok);
539 bmap = isl_basic_map_extend(s->ctx, bmap, bmap->nparam,
540 bmap->n_in, bmap->n_out, 0, 0, 1);
541 k = isl_basic_map_alloc_inequality(s->ctx, bmap);
544 isl_seq_clr(bmap->ineq[k], 1+total);
547 tok = stream_next_token(s);
549 stream_error(s, NULL, "unexpected EOF");
552 if (tok->type == TOKEN_IDENT) {
554 int pos = vars_pos(*v, tok->u.s, -1);
558 stream_error(s, tok, "unknown identifier");
562 isl_int_add_ui(bmap->ineq[k][1+pos],
563 bmap->ineq[k][1+pos], 1);
565 isl_int_sub_ui(bmap->ineq[k][1+pos],
566 bmap->ineq[k][1+pos], 1);
567 } else if (tok->type == TOKEN_VALUE) {
571 tok2 = stream_next_token(s);
572 if (tok2 && tok2->type == TOKEN_IDENT) {
573 pos = vars_pos(*v, tok2->u.s, -1);
577 stream_error(s, tok2,
578 "unknown identifier");
584 stream_push_token(s, tok2);
586 isl_int_neg(tok->u.v, tok->u.v);
587 isl_int_add(bmap->ineq[k][1+pos],
588 bmap->ineq[k][1+pos], tok->u.v);
589 } else if (tok->type == TOKEN_LE) {
591 isl_seq_neg(bmap->ineq[k], bmap->ineq[k], 1+total);
592 } else if (tok->type == TOKEN_GE) {
595 } else if (tok->type == '=') {
597 stream_error(s, tok, "too many operators");
604 stream_push_token(s, tok);
611 stream_error(s, tok, "missing operator");
615 isl_basic_map_inequality_to_equality(s->ctx, bmap, k);
620 isl_basic_map_free(s->ctx, bmap);
624 static struct isl_basic_map *add_constraints(struct stream *s,
625 struct vars **v, struct isl_basic_map *bmap)
630 bmap = add_constraint(s, v, bmap);
633 tok = stream_next_token(s);
635 stream_error(s, NULL, "unexpected EOF");
638 if (tok->type != TOKEN_AND)
642 stream_push_token(s, tok);
648 isl_basic_map_free(s->ctx, bmap);
652 static struct isl_basic_map *basic_map_read(struct stream *s)
654 struct isl_basic_map *bmap = NULL;
656 struct vars *v = NULL;
660 tok = stream_next_token(s);
661 if (!tok || tok->type != '{') {
662 stream_error(s, tok, "expecting '{'");
664 stream_push_token(s, tok);
668 v = vars_new(s->ctx);
669 v = read_tuple(s, v);
673 tok = stream_next_token(s);
674 if (tok && tok->type == TOKEN_TO) {
676 v = read_tuple(s, v);
682 stream_push_token(s, tok);
686 bmap = isl_basic_map_alloc(s->ctx, 0, n1, n2, 0, 0,0);
689 tok = stream_next_token(s);
690 if (tok && tok->type == ':') {
692 bmap = add_constraints(s, &v, bmap);
693 tok = stream_next_token(s);
695 if (tok && tok->type == '}') {
698 stream_error(s, tok, "unexpected token");
707 isl_basic_map_free(s->ctx, bmap);
713 struct isl_basic_map *isl_basic_map_read_from_file_omega(
714 struct isl_ctx *ctx, FILE *input)
716 struct isl_basic_map *bmap;
717 struct stream *s = stream_new_file(ctx, input);
720 bmap = basic_map_read(s);
725 struct isl_basic_set *isl_basic_set_read_from_file_omega(
726 struct isl_ctx *ctx, FILE *input)
728 struct isl_basic_map *bmap;
729 bmap = isl_basic_map_read_from_file_omega(ctx, input);
732 isl_assert(ctx, bmap->n_in == 0, goto error);
733 return (struct isl_basic_set *)bmap;
735 isl_basic_map_free(ctx, bmap);