From 491dbcb9116954c72a078d02bdc7082cbdb294b5 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Tue, 26 Jul 2011 15:39:50 +0200 Subject: [PATCH] isl_stream_read_map: handle initial parenthesized affine expressions Before, the parser would assume the expression to be a condition. Now it can handle both cases. Signed-off-by: Sven Verdoolaege --- isl_input.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- isl_test.c | 4 +++ 2 files changed, 103 insertions(+), 5 deletions(-) diff --git a/isl_input.c b/isl_input.c index 6fc61a4..b31728a 100644 --- a/isl_input.c +++ b/isl_input.c @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include "isl_polynomial_private.h" #include @@ -358,7 +358,11 @@ static __isl_give isl_pw_aff *accept_affine_factor(struct isl_stream *s, isl_stream_error(s, NULL, "unexpected EOF"); goto error; } - if (tok->type == ISL_TOKEN_IDENT) { + + if (tok->type == ISL_TOKEN_AFF) { + res = isl_pw_aff_copy(tok->u.pwaff); + isl_token_free(tok); + } else if (tok->type == ISL_TOKEN_IDENT) { int n = v->n; int pos = vars_pos(v, tok->u.s, -1); isl_aff *aff; @@ -476,7 +480,8 @@ static __isl_give isl_pw_aff *accept_affine(struct isl_stream *s, tok->type == ISL_TOKEN_MIN || tok->type == ISL_TOKEN_MAX || tok->type == ISL_TOKEN_FLOORD || tok->type == ISL_TOKEN_CEILD || - tok->type == ISL_TOKEN_IDENT) { + tok->type == ISL_TOKEN_IDENT || + tok->type == ISL_TOKEN_AFF) { isl_pw_aff *term; isl_stream_push_token(s, tok); tok = NULL; @@ -930,13 +935,102 @@ error: return NULL; } -static __isl_give isl_map *read_conjunct(struct isl_stream *s, +/* Parse an expression between parentheses and push the result + * back on the stream. + * + * The parsed expression may be either an affine expression + * or a condition. The first type is pushed onto the stream + * as an isl_pw_aff, while the second is pushed as an isl_map. + * + * If the initial token indicates the start of a condition, + * we parse it as such. + * Otherwise, we first parse an affine expression and push + * that onto the stream. If the affine expression covers the + * entire expression between parentheses, we return. + * Otherwise, we assume that the affine expression is the + * start of a condition and continue parsing. + */ +static int resolve_paren_expr(struct isl_stream *s, struct vars *v, __isl_take isl_map *map) { - if (isl_stream_eat_if_available(s, '(')) { + struct isl_token *tok, *tok2; + int line, col; + isl_pw_aff *pwaff; + + tok = isl_stream_next_token(s); + if (!tok || tok->type != '(') + goto error; + + if (isl_stream_next_token_is(s, ISL_TOKEN_EXISTS) || + isl_stream_next_token_is(s, ISL_TOKEN_TRUE) || + isl_stream_next_token_is(s, ISL_TOKEN_FALSE)) { map = read_disjuncts(s, v, map); if (isl_stream_eat(s, ')')) goto error; + tok->type = ISL_TOKEN_MAP; + tok->u.map = map; + isl_stream_push_token(s, tok); + return 0; + } + + tok2 = isl_stream_next_token(s); + if (!tok2) + goto error; + line = tok2->line; + col = tok2->col; + isl_stream_push_token(s, tok2); + + pwaff = accept_affine(s, isl_dim_wrap(isl_map_get_dim(map)), v); + if (!pwaff) + goto error; + + tok2 = isl_token_new(s->ctx, line, col, 0); + if (!tok2) + goto error2; + tok2->type = ISL_TOKEN_AFF; + tok2->u.pwaff = pwaff; + + if (isl_stream_eat_if_available(s, ')')) { + isl_stream_push_token(s, tok2); + isl_token_free(tok); + isl_map_free(map); + return 0; + } + + isl_stream_push_token(s, tok2); + + map = read_disjuncts(s, v, map); + if (isl_stream_eat(s, ')')) + goto error; + + tok->type = ISL_TOKEN_MAP; + tok->u.map = map; + isl_stream_push_token(s, tok); + + return 0; +error2: + isl_pw_aff_free(pwaff); +error: + isl_token_free(tok); + isl_map_free(map); + return -1; +} + +static __isl_give isl_map *read_conjunct(struct isl_stream *s, + struct vars *v, __isl_take isl_map *map) +{ + if (isl_stream_next_token_is(s, '(')) + if (resolve_paren_expr(s, v, isl_map_copy(map))) + goto error; + + if (isl_stream_next_token_is(s, ISL_TOKEN_MAP)) { + struct isl_token *tok; + tok = isl_stream_next_token(s); + if (!tok) + goto error; + isl_map_free(map); + map = isl_map_copy(tok->u.map); + isl_token_free(tok); return map; } diff --git a/isl_test.c b/isl_test.c index c5e3e83..82e2e5e 100644 --- a/isl_test.c +++ b/isl_test.c @@ -128,6 +128,10 @@ void test_parse(struct isl_ctx *ctx) str2 = "{ [i,j] : i < j or i > j }"; test_parse_map_equal(ctx, str, str2); + str = "{ [i,j] : (i+1)*2 >= j }"; + str2 = "{ [i, j] : j <= 2 + 2i }"; + test_parse_map_equal(ctx, str, str2); + test_parse_pwqp(ctx, "{ [i] -> i + [ (i + [i/3])/2 ] }"); test_parse_map(ctx, "{ S1[i] -> [([i/10]),i%10] : 0 <= i <= 45 }"); } -- 2.7.4