From e0ddf32d2e8d0742278552aff52875b1d2fab4b3 Mon Sep 17 00:00:00 2001 From: "Wolfgang (Blub) Bumiller" Date: Wed, 21 Nov 2012 20:36:42 +0100 Subject: [PATCH] parsing the ternary --- lexer.c | 2 +- lexer.h | 4 +++- parser.c | 19 +++++++++++++++++-- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/lexer.c b/lexer.c index c6e8552..5a1f23e 100644 --- a/lexer.c +++ b/lexer.c @@ -1021,6 +1021,7 @@ int lex_do(lex_file *lex) { case '[': case '(': + case ':': lex_tokench(lex, ch); lex_endtoken(lex); if (lex->flags.noops) @@ -1029,7 +1030,6 @@ int lex_do(lex_file *lex) return (lex->tok.ttype = TOKEN_OPERATOR); case ')': case ';': - case ':': case '{': case '}': case ']': diff --git a/lexer.h b/lexer.h index 137bfe9..a6f9100 100644 --- a/lexer.h +++ b/lexer.h @@ -207,6 +207,7 @@ static const oper_info c_operators[] = { { "||", 2, opid2('|','|'), ASSOC_LEFT, 4, 0 }, { "?", 3, opid2('?',':'), ASSOC_RIGHT, 3, 0 }, + { ":", 3, opid2(':','?'), ASSOC_RIGHT, 3, 0 }, { "=", 2, opid1('='), ASSOC_RIGHT, 2, 0 }, { "+=", 2, opid2('+','='), ASSOC_RIGHT, 2, 0 }, @@ -262,9 +263,10 @@ static const oper_info qcc_operators[] = { { "&&", 2, opid2('&','&'), ASSOC_LEFT, 5, 0 }, { "||", 2, opid2('|','|'), ASSOC_LEFT, 5, 0 }, - { ",", 2, opid1(','), ASSOC_LEFT, 2, 0 } + { ",", 2, opid1(','), ASSOC_LEFT, 2, 0 }, { "?", 3, opid2('?',':'), ASSOC_RIGHT, 1, 0 }, + { ":", 3, opid2(':','?'), ASSOC_RIGHT, 1, 0 } }; static const size_t qcc_operator_count = (sizeof(qcc_operators) / sizeof(qcc_operators[0])); diff --git a/parser.c b/parser.c index 99b7eb7..6553509 100644 --- a/parser.c +++ b/parser.c @@ -1080,6 +1080,7 @@ static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma * end of a condition is an unmatched closing paren */ int parens = 0; + int ternaries = 0; sy.out = NULL; sy.ops = NULL; @@ -1267,6 +1268,12 @@ static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma break; } + /* a colon without a pervious question mark cannot be a ternary */ + if (op->id == opid2(':','?')) { + parser->tok = ':'; + break; + } + if (vec_size(sy.ops) && !vec_last(sy.ops).paren) olast = &operators[vec_last(sy.ops).etype-1]; @@ -1323,6 +1330,15 @@ static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma vec_push(sy.ops, syop(parser_ctx(parser), op)); vec_push(sy.ops, syparen(parser_ctx(parser), SY_PAREN_INDEX, 0)); wantop = false; + } else if (op->id == opid2('?',':')) { + wantop = false; + vec_push(sy.ops, syop(parser_ctx(parser), op)); + wantop = false; + --ternaries; + } else if (op->id == opid2(':','?')) { + /* we don't push this operator */ + wantop = false; + ++ternaries; } else { DEBUGSHUNTDO(con_out("push operator %s\n", op->op)); vec_push(sy.ops, syop(parser_ctx(parser), op)); @@ -1333,8 +1349,7 @@ static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma goto onerr; } if (parser->tok == ';' || - (!parens && parser->tok == ']') || - parser->tok == ':') + (!parens && parser->tok == ']')) { break; } -- 2.39.2