diff options
author | Richard Biener <rguenther@suse.de> | 2015-07-15 08:35:15 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2015-07-15 08:35:15 +0000 |
commit | 64d3a1f040ce15fc5941da2d5f1f79b7f085ebf1 (patch) | |
tree | 507b45542db33a685cd0956de8a295ab1a81916a /gcc/genmatch.c | |
parent | a16bca311ae96780b64f3652538e9b22ccee54e6 (diff) | |
download | gcc-64d3a1f040ce15fc5941da2d5f1f79b7f085ebf1.zip gcc-64d3a1f040ce15fc5941da2d5f1f79b7f085ebf1.tar.gz gcc-64d3a1f040ce15fc5941da2d5f1f79b7f085ebf1.tar.bz2 |
genmatch.c (parser::peek, [...]): Add argument to tell how many tokens to peek ahead (default 1).
2015-07-15 Richard Biener <rguenther@suse.de>
* genmatch.c (parser::peek, parser::peek_ident): Add argument
to tell how many tokens to peek ahead (default 1).
(parser::eat_token, parser::eat_ident): Return token consumed.
(parser::parse_result): Parse new switch statement.
* match.pd: Use case statements where appropriate.
From-SVN: r225809
Diffstat (limited to 'gcc/genmatch.c')
-rw-r--r-- | gcc/genmatch.c | 78 |
1 files changed, 66 insertions, 12 deletions
diff --git a/gcc/genmatch.c b/gcc/genmatch.c index fa140df..1434719 100644 --- a/gcc/genmatch.c +++ b/gcc/genmatch.c @@ -3014,13 +3014,13 @@ public: private: const cpp_token *next (); - const cpp_token *peek (); - const cpp_token *peek_ident (const char * = NULL); + const cpp_token *peek (unsigned = 1); + const cpp_token *peek_ident (const char * = NULL, unsigned = 1); const cpp_token *expect (enum cpp_ttype); - void eat_token (enum cpp_ttype); + const cpp_token *eat_token (enum cpp_ttype); const char *get_string (); const char *get_ident (); - void eat_ident (const char *); + const cpp_token *eat_ident (const char *); const char *get_number (); id_base *parse_operation (); @@ -3078,7 +3078,7 @@ parser::next () /* Peek at the next non-whitespace token from R. */ const cpp_token * -parser::peek () +parser::peek (unsigned num) { const cpp_token *token; unsigned i = 0; @@ -3086,8 +3086,9 @@ parser::peek () { token = cpp_peek_token (r, i++); } - while (token->type == CPP_PADDING - && token->type != CPP_EOF); + while ((token->type == CPP_PADDING + && token->type != CPP_EOF) + || (--num > 0)); /* If we peek at EOF this is a fatal error as it leaves the cpp_reader in unusable state. Assume we really wanted a token and thus this EOF is unexpected. */ @@ -3100,9 +3101,9 @@ parser::peek () token is not an identifier or equal to ID if supplied). */ const cpp_token * -parser::peek_ident (const char *id) +parser::peek_ident (const char *id, unsigned num) { - const cpp_token *token = peek (); + const cpp_token *token = peek (num); if (token->type != CPP_NAME) return 0; @@ -3131,10 +3132,10 @@ parser::expect (enum cpp_ttype tk) /* Consume the next token from R and assert it is of type TK. */ -void +const cpp_token * parser::eat_token (enum cpp_ttype tk) { - expect (tk); + return expect (tk); } /* Read the next token from R and assert it is of type CPP_STRING and @@ -3159,13 +3160,14 @@ parser::get_ident () /* Eat an identifier token with value S from R. */ -void +const cpp_token * parser::eat_ident (const char *s) { const cpp_token *token = peek (); const char *t = get_ident (); if (strcmp (s, t) != 0) fatal_at (token, "expected '%s' got '%s'\n", s, t); + return token; } /* Read the next token from R and assert it is of type CPP_NUMBER and @@ -3557,6 +3559,58 @@ parser::parse_result (operand *result, predicate_id *matcher) eat_token (CPP_CLOSE_PAREN); return withe; } + else if (peek_ident ("switch")) + { + token = eat_ident ("switch"); + eat_token (CPP_OPEN_PAREN); + eat_ident ("if"); + if_expr *ife = new if_expr (); + operand *res = ife; + ife->cond = parse_c_expr (CPP_OPEN_PAREN); + if (peek ()->type == CPP_OPEN_PAREN) + ife->trueexpr = parse_result (result, matcher); + else + ife->trueexpr = parse_op (); + eat_token (CPP_CLOSE_PAREN); + if (peek ()->type != CPP_OPEN_PAREN + || !peek_ident ("if", 2)) + fatal_at (token, "switch can be implemented with a single if"); + while (peek ()->type != CPP_CLOSE_PAREN) + { + if (peek ()->type == CPP_OPEN_PAREN) + { + if (peek_ident ("if", 2)) + { + eat_token (CPP_OPEN_PAREN); + eat_ident ("if"); + ife->falseexpr = new if_expr (); + ife = as_a <if_expr *> (ife->falseexpr); + ife->cond = parse_c_expr (CPP_OPEN_PAREN); + if (peek ()->type == CPP_OPEN_PAREN) + ife->trueexpr = parse_result (result, matcher); + else + ife->trueexpr = parse_op (); + eat_token (CPP_CLOSE_PAREN); + } + else + { + /* switch default clause */ + ife->falseexpr = parse_result (result, matcher); + eat_token (CPP_CLOSE_PAREN); + return res; + } + } + else + { + /* switch default clause */ + ife->falseexpr = parse_op (); + eat_token (CPP_CLOSE_PAREN); + return res; + } + } + eat_token (CPP_CLOSE_PAREN); + return res; + } else { operand *op = result; |