From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 97183 invoked by alias); 4 Jan 2019 20:25:27 -0000 Mailing-List: contact gcc-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-owner@gcc.gnu.org Received: (qmail 97165 invoked by uid 89); 4 Jan 2019 20:25:26 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00,FREEMAIL_FROM,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,RCVD_IN_DNSWL_NONE,SPF_PASS autolearn=ham version=3.3.2 spammy=recovered, nesting, hello!, water X-HELO: mail-it1-f179.google.com Received: from mail-it1-f179.google.com (HELO mail-it1-f179.google.com) (209.85.166.179) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 04 Jan 2019 20:25:24 +0000 Received: by mail-it1-f179.google.com with SMTP id g76so3250108itg.2 for ; Fri, 04 Jan 2019 12:25:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:from:date:message-id:subject:to :content-transfer-encoding; bh=ip7oQrars/TWo4uCtagp98dRoH+m4hDqAuyxuPKadSI=; b=dxINim8qtYMhlBP0y7Y7H1KOwJoYWA8fiyn06Fhf/M5lS8K0ZdchQGmnsmNjLGKM8G rFDmEqdliZTi3l/v3jKTqUhAc2gZ1vYd2LJwsPmnsFUWVGjl+1kYMTD6w1sa58NXlEB+ AXNvSElOk8IvNft1fkJ5O3Wh14d98UzHxMBb/ljIgKcCfYA6WcoeOtgv1povgzQJbiI/ KWvMX0YhSApW8ZeA17GUDG6ZiTMKk/R327cr35fWxU5UlE0glisCNcPlQTB7UMNnTMZf VEzxnNThLA8xI23EzTt+aSCZc3n/PNBdQoFv2gOG/fXoYaosdDfq1PnHW/uWP6ZyJLVA D2vw== MIME-Version: 1.0 From: =?UTF-8?Q?Daniel_Marjam=C3=A4ki?= Date: Fri, 04 Jan 2019 20:25:00 -0000 Message-ID: Subject: Improve syntax error To: gcc@gcc.gnu.org Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-IsSubscribed: yes X-SW-Source: 2019-01/txt/msg00012.txt.bz2 Hello! I just chose the word "unmatched" for now.. let me know if "stray" or some other word is better. :-) I have a work in progress patch that as far as I can tell works. I wonder if you see some problems with my design. What do I need to do..? Basically I have chosen to add a nesting_depth to the c_parser struct. That is updated in the consume_token. I first tried to add such variable in c_parser_declaration_or_fndef() but that was much more difficult. I wanted to warn about unmatched }. It is however more complicated than I thought. For two reasons: The first reason is the hard problem, but maybe we can ignore this now also: void f() { } // <- looking at the indentation, it seems preferable to warn about = this } The second reason is easier.. I just don't want to get into too deep water too quickly. To warn about that also I can't just have a nesting_depth anymore. I need to have a stack that track the nesting. I have experimented with a linked list like this and made it work: struct nesting { cpp_ttype type; struct nesting *next; }; but well here I run into memory management and I also wonder if you like the design decision to put a linked list in the c_parser struct. Here is my current patch... diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index 972b629c092..eabc5ffa15e 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -171,6 +171,8 @@ struct GTY(()) c_parser { /* How many look-ahead tokens are available (0 - 4, or more if parsing from pre-lexed tokens). */ unsigned int tokens_avail; + /* nesting depth in expression (parentheses / squares) */ + unsigned int nesting_depth; /* True if a syntax error is being recovered from; false otherwise. c_parser_error sets this flag. It should clear this flag when enough tokens have been consumed to recover from the error. */ @@ -763,6 +765,22 @@ c_parser_next_tokens_start_declaration (c_parser *pars= er) return false; } +/* Nesting start token */ + +static bool c_parser_is_nesting_start (c_parser *parser) +{ + return c_parser_next_token_is (parser, CPP_OPEN_PAREN) || + c_parser_next_token_is (parser, CPP_OPEN_SQUARE); +} + +/* Nesting end token */ + +static bool c_parser_is_nesting_end (c_parser *parser) +{ + return c_parser_next_token_is (parser, CPP_CLOSE_PAREN) || + c_parser_next_token_is (parser, CPP_CLOSE_SQUARE); +} + /* Consume the next token from PARSER. */ void @@ -772,6 +790,10 @@ c_parser_consume_token (c_parser *parser) gcc_assert (parser->tokens[0].type !=3D CPP_EOF); gcc_assert (!parser->in_pragma || parser->tokens[0].type !=3D CPP_PRAGMA= _EOL); gcc_assert (parser->error || parser->tokens[0].type !=3D CPP_PRAGMA); + if (c_parser_is_nesting_start (parser)) + parser->nesting_depth++; + else if (parser->nesting_depth > 0 && c_parser_is_nesting_end (parser)) + parser->nesting_depth--; parser->last_token_location =3D parser->tokens[0].location; if (parser->tokens !=3D &parser->tokens_buf[0]) parser->tokens++; @@ -1673,6 +1695,20 @@ add_debug_begin_stmt (location_t loc) add_stmt (stmt); } +static bool c_parser_unmatched_p (c_parser *parser) +{ + if (c_parser_is_nesting_end (parser)) + return parser->nesting_depth =3D=3D 0; + return false; +} + +static void complain_about_unmatched_token (c_parser *parser) +{ + c_token *token =3D c_parser_peek_token(parser); + error_at (token->location, "unmatched %<%s%>", + cpp_type2name(token->type, token->flags)); +} + /* Parse a declaration or function definition (C90 6.5, 6.7.1, C99 6.7, 6.9.1, C11 6.7, 6.9.1). If FNDEF_OK is true, a function definition is accepted; otherwise (old-style parameter declarations) only other @@ -2228,7 +2264,10 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, } else { - c_parser_error (parser, "expected %<,%> or %<;%>"); + if (c_parser_unmatched_p (parser)) + complain_about_unmatched_token (parser); + else + c_parser_error (parser, "expected %<,%> or %<;%>"); c_parser_skip_to_end_of_block_or_statement (parser); return; } diff --git a/gcc/testsuite/gcc.dg/unmatched.c b/gcc/testsuite/gcc.dg/unmatc= hed.c new file mode 100644 index 00000000000..bd458a01109 --- /dev/null +++ b/gcc/testsuite/gcc.dg/unmatched.c @@ -0,0 +1,19 @@ + +/* { dg-do compile } */ + +void f1() { + int a =3D 0)+3; /* { dg-error "unmatched" } */ +} + +void f2() { + int b =3D (1]+3; /* { dg-error "expected" } */ +} + +void f3() { + int b =3D 1]+3; /* { dg-error "unmatched" } */ +} + +void f4() { + int c =3D (1))+3; /* { dg-error "unmatched" } */ +} + Best regards, Daniel Marjam=C3=A4ki