mirror of
https://github.com/DarkPlacesEngine/gmqcc.git
synced 2025-02-20 18:32:01 +00:00
parsing the ternary
This commit is contained in:
parent
8517221b1b
commit
e0ddf32d2e
3 changed files with 21 additions and 4 deletions
2
lexer.c
2
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 ']':
|
||||
|
|
4
lexer.h
4
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]));
|
||||
|
||||
|
|
19
parser.c
19
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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue