From: Wolfgang (Blub) Bumiller Date: Mon, 3 Dec 2012 19:37:02 +0000 (+0100) Subject: Parsing noref-pragma X-Git-Tag: 0.1.9~120 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=88a4721de7cf208f0cf10ee03ac94df914273da2;p=xonotic%2Fgmqcc.git Parsing noref-pragma --- diff --git a/lexer.c b/lexer.c index 4d283f4..8e783e6 100644 --- a/lexer.c +++ b/lexer.c @@ -492,6 +492,7 @@ unroll: vec_pop(command); } vec_free(command); + lex_ungetch(lex, ' '); } if (command) { vec_pop(command); @@ -500,6 +501,7 @@ unroll: vec_pop(command); } vec_free(command); + lex_ungetch(lex, ' '); } if (pragma) { vec_pop(pragma); diff --git a/parser.c b/parser.c index c3c4fa2..5f2f7da 100644 --- a/parser.c +++ b/parser.c @@ -93,6 +93,9 @@ typedef struct { * we shall trigger -Wternary-precedence. */ enum { POT_PAREN, POT_TERNARY1, POT_TERNARY2 } *pot; + + /* pragma flags */ + bool noref; } parser_t; static void parser_enterblock(parser_t *parser); @@ -2398,6 +2401,75 @@ static bool parse_goto(parser_t *parser, ast_expression **out) return true; } +static bool parse_skipwhite(parser_t *parser) +{ + do { + if (!parser_next(parser)) + return false; + } while (parser->tok == TOKEN_WHITE && parser->tok < TOKEN_ERROR); + return parser->tok < TOKEN_ERROR; +} + +static bool parse_eol(parser_t *parser) +{ + if (!parse_skipwhite(parser)) + return false; + return parser->tok == TOKEN_EOL; +} + +static bool parse_pragma_do(parser_t *parser) +{ + if (!parser_next(parser) || + parser->tok != TOKEN_IDENT || + strcmp(parser_tokval(parser), "pragma")) + { + parseerror(parser, "expected `pragma` keyword after `#`, got `%s`", parser_tokval(parser)); + return false; + } + if (!parse_skipwhite(parser) || parser->tok != TOKEN_IDENT) { + parseerror(parser, "expected pragma, got `%s`", parser_tokval(parser)); + return false; + } + + if (!strcmp(parser_tokval(parser), "noref")) { + if (!parse_skipwhite(parser) || parser->tok != TOKEN_INTCONST) { + parseerror(parser, "`noref` pragma requires an argument: 0 or 1"); + return false; + } + parser->noref = !!parser_token(parser)->constval.i; + if (!parse_eol(parser)) { + parseerror(parser, "parse error after `noref` pragma"); + return false; + } + } + else + { + parseerror(parser, "unrecognized hash-keyword: `%s`", parser_tokval(parser)); + return false; + } + + return true; +} + +static bool parse_pragma(parser_t *parser) +{ + bool rv; + parser->lex->flags.preprocessing = true; + parser->lex->flags.mergelines = true; + rv = parse_pragma_do(parser); + if (parser->tok != TOKEN_EOL) { + parseerror(parser, "junk after pragma"); + rv = false; + } + parser->lex->flags.preprocessing = false; + parser->lex->flags.mergelines = false; + if (!parser_next(parser)) { + parseerror(parser, "parse error after pragma"); + rv = false; + } + return rv; +} + static bool parse_statement(parser_t *parser, ast_block *block, ast_expression **out, bool allow_cases) { int cvq; @@ -4266,6 +4338,10 @@ static bool parser_global_statement(parser_t *parser) parseerror(parser, "unrecognized keyword `%s`", parser_tokval(parser)); return false; } + else if (parser->tok == '#') + { + return parse_pragma(parser); + } else if (parser->tok == '$') { if (!parser_next(parser)) {