Lemon-generated parser gives an assertion failure

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Lemon-generated parser gives an assertion failure

Guy Harris
If you use the version of lemon.c and lempar.c in the Fossil repository for SQLite as of 2017-04-16 20:54:23 UTC, take the following Lemon parser, compile it, and run it, it fails with

        Assertion failed: (yyruleno!=116), function yy_reduce, file mate_grammar.c, line 2165.

(It's a grammar for a domain-specific language in Wireshark, with the actions trimmed down to avoid having to drag in the entire MATE mechanism, and other changes to make it a stand-along program.  As such, you get a bunch of warnings from Lemon about unused labels; ignore them.)

%include {

/* mate_grammar.lemon
* MATE's configuration language grammar
*
* Copyright 2005, Luis E. Garcia Ontanon <[hidden email]>
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <[hidden email]>
* Copyright 1998 Gerald Combs
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>

#include "mate_grammar.h"

typedef enum _gop_tree_mode_t {
        GOP_NULL_TREE,
        GOP_BASIC_TREE,
        GOP_FULL_TREE
} gop_tree_mode_t;

typedef enum _gop_pdu_tree {
        GOP_NO_TREE,
        GOP_PDU_TREE,
        GOP_FRAME_TREE,
        GOP_BASIC_PDU_TREE
} gop_pdu_tree_t;

typedef enum _accept_mode_t {
        ACCEPT_MODE,
        REJECT_MODE
} accept_mode_t;
typedef enum _avpl_match_mode {
        AVPL_NO_MATCH,
        AVPL_STRICT,
        AVPL_LOOSE,
        AVPL_EVERY
} avpl_match_mode;

typedef enum _avpl_replace_mode {
        AVPL_NO_REPLACE,
        AVPL_INSERT,
        AVPL_REPLACE
} avpl_replace_mode;

#define DUMMY void*

#define MATE_PARSE(token_type, text) \
        MateParser(pParser, (token_type), strdup(text));

int
main(void)
{
        void MateParser(void*,int, char*);
        void *MateParserAlloc(void *(*)(size_t));
        void MateParserFree( void*, void(*)(void*) );
        void MateParseTrace(FILE*,char*);
        void* pParser;

        pParser = MateParserAlloc(malloc);

        /* Here come the tokens */
        MATE_PARSE(TOKEN_PDU_KW, "Pdu");
        MATE_PARSE(TOKEN_NAME, "sip_pdu");
        MATE_PARSE(TOKEN_PROTO_KW, "Proto");
        MATE_PARSE(TOKEN_NAME, "sip");
        MATE_PARSE(TOKEN_TRANSPORT_KW, "Transport");
        MATE_PARSE(TOKEN_NAME, "ip");
        MATE_PARSE(TOKEN_OPEN_BRACE, "{");
        MATE_PARSE(TOKEN_EXTRACT_KW, "Extract");
        MATE_PARSE(TOKEN_NAME, "call_id");
        MATE_PARSE(TOKEN_FROM_KW, "From");
        MATE_PARSE(TOKEN_NAME, "sip.Call-Id");
        MATE_PARSE(TOKEN_SEMICOLON, ";");
        MATE_PARSE(TOKEN_EXTRACT_KW, "Extract");
        MATE_PARSE(TOKEN_NAME, "method");
        MATE_PARSE(TOKEN_FROM_KW, "From");
        MATE_PARSE(TOKEN_NAME, "sip.Method");
        MATE_PARSE(TOKEN_SEMICOLON, ";");
        MATE_PARSE(TOKEN_CLOSE_BRACE, "}");
        MATE_PARSE(TOKEN_GOP_KW, "Gop");
        MATE_PARSE(TOKEN_NAME, "sip");
        MATE_PARSE(TOKEN_ON_KW, "On");
        MATE_PARSE(TOKEN_NAME, "sip_pdu");
        MATE_PARSE(TOKEN_MATCH_KW, "Match");
        MATE_PARSE(TOKEN_OPEN_PARENS, "(");
        MATE_PARSE(TOKEN_NAME, "call_id");
        MATE_PARSE(TOKEN_CLOSE_PARENS, ")");
        MATE_PARSE(TOKEN_OPEN_BRACE, "{");
        MATE_PARSE(TOKEN_START_KW, "Start");
        MATE_PARSE(TOKEN_OPEN_PARENS, "(");
        MATE_PARSE(TOKEN_NAME, "method");
        MATE_PARSE(TOKEN_AVP_OPERATOR, "=");
        MATE_PARSE(TOKEN_QUOTED, "SUBSCRIBE");
        MATE_PARSE(TOKEN_CLOSE_PARENS, ")");
        MATE_PARSE(TOKEN_SEMICOLON, ";");
        MATE_PARSE(TOKEN_STOP_KW, "Stop");
        MATE_PARSE(TOKEN_OPEN_PARENS, "(");
        MATE_PARSE(TOKEN_NAME, "method");
        MATE_PARSE(TOKEN_AVP_OPERATOR, "=");
        MATE_PARSE(TOKEN_QUOTED, "NOTIFY");
        MATE_PARSE(TOKEN_CLOSE_PARENS, ")");
        MATE_PARSE(TOKEN_SEMICOLON, ";");
        MATE_PARSE(TOKEN_CLOSE_BRACE, "}");
        MATE_PARSE(TOKEN_DONE_KW, "Done");
        MATE_PARSE(TOKEN_SEMICOLON, ";");

        /* Inform parser that end of input has reached. */
        MateParser(pParser, 0, NULL);

        MateParserFree(pParser, free);
}

}

%name MateParser

%token_prefix TOKEN_

%token_type { char* }
%token_destructor {
        if ($$) free($$);
}

%syntax_error {
        fprintf(stderr, "Syntax Error before %s",yyminor);
}

%parse_failure {
        fprintf(stderr, "Parse Error");
}

%type   transform_decl  { char* }
%type   transform_body { char* }
%type   transform_statements { char* }
%type   transform_statement { char* }
%type   transform_match { char* }
%type   transform_action { char* }
%type   match_mode { avpl_match_mode }
%type   action_mode { avpl_replace_mode }

%type gop_name { char* }
%type time_value { float }
%type pdu_name { char* }
%type gop_tree_mode { gop_tree_mode_t }
%type true_false { int }

%type criteria_statement { char* }
%type accept_mode { accept_mode_t }
%type pdu_drop_unassigned_statement { int }
%type discard_pdu_data_statement { int }
%type last_extracted_statement { int }

%type extraction_statement {char*}
%type extraction_statements {char*}

%type gop_options { char* }

%type gop_start_statement { char* }
%type gop_stop_statement { char* }
%type extra_statement { char* }
%type gop_drop_unassigned_statement { int }
%type show_goptree_statement { gop_tree_mode_t }
%type show_times_statement { int }
%type gop_expiration_statement { float }
%type idle_timeout_statement { float }
%type lifetime_statement { float }

%type gog_statements { char* }
%type gog_expiration_statement { float }
%type gog_goptree_statement { gop_tree_mode_t }
%type gog_key_statements { char* }
%type gog_key_statement { char* }
%type transform_list_statement { char* }
%type transform { char* }
%type gop_tree_type { gop_tree_mode_t }

%type payload_statement { char* }
%type proto_stack { char*  }
%type field { char* }
%type transform_list { char* }
%type avpl { char* }
%type avps { char* }
%type avp { char* }
%type value { char* }
%type avp_oneoff { char* }


mate_config ::= decls.

decls ::= decls decl.
decls ::= .

decl ::= pdu_decl.
decl ::= gop_decl.
decl ::= gog_decl.
decl ::= transform_decl.
decl ::= defaults_decl.
decl ::= debug_decl.
decl ::= DONE_KW SEMICOLON.

/************* DEBUG
*/

debug_decl ::= DEBUG_KW OPEN_BRACE dbgfile_default dbglevel_default pdu_dbglevel_default gop_dbglevel_default gog_dbglevel_default CLOSE_BRACE SEMICOLON.

dbgfile_default ::= FILENAME_KW QUOTED(Filename) SEMICOLON. { printf("dbgfile_default\n"); }
dbgfile_default ::= FILENAME_KW NAME(Filename) SEMICOLON. { printf("dbgfile_default\n"); }
dbgfile_default ::= .

dbglevel_default ::= LEVEL_KW INTEGER(LevelString) SEMICOLON. { printf("dbglevel_default\n"); }
dbglevel_default ::= .

pdu_dbglevel_default ::= PDU_KW LEVEL_KW INTEGER(LevelString) SEMICOLON. { printf("pdu_dbglevel_default\n"); }
pdu_dbglevel_default ::= .

gop_dbglevel_default ::= GOP_KW LEVEL_KW INTEGER(LevelString) SEMICOLON. { printf("gop_dbglevel_default\n"); }
gop_dbglevel_default ::= .

gog_dbglevel_default ::= GOG_KW LEVEL_KW INTEGER(LevelString) SEMICOLON. { printf("gog_dbglevel_default\n"); }
gog_dbglevel_default ::= .


/************* DEFAULTS
*/

defaults_decl ::= DEFAULT_KW OPEN_BRACE pdu_defaults gop_defaults gog_defaults CLOSE_BRACE SEMICOLON.

pdu_defaults ::= PDU_KW OPEN_BRACE pdu_last_extracted_default pdu_drop_unassigned_default pdu_discard_default CLOSE_BRACE SEMICOLON.
pdu_defaults ::= .

pdu_last_extracted_default ::= LAST_EXTRACTED_KW true_false(Flag) SEMICOLON. { printf("pdu_last_extracted_default\n"); }
pdu_last_extracted_default ::= .

pdu_drop_unassigned_default ::= DROP_UNASSIGNED_KW true_false(Flag) SEMICOLON. { printf("pdu_drop_unassigned_default\n"); }
pdu_drop_unassigned_default ::= .

pdu_discard_default ::= DISCARD_PDU_DATA_KW true_false(Flag) SEMICOLON. { printf("pdu_discard_default\n"); }
pdu_discard_default ::= .

gop_defaults ::= GOP_KW OPEN_BRACE gop_expiration_default gop_idle_timeout_default gop_lifetime_default gop_drop_unassigned_default gop_tree_mode_default gop_show_times_default  CLOSE_BRACE SEMICOLON.
gop_defaults ::= .

gop_expiration_default ::= EXPIRATION_KW time_value(B) SEMICOLON. { printf("gop_expiration_default\n"); }
gop_expiration_default ::= .

gop_idle_timeout_default ::= IDLE_TIMEOUT_KW time_value(B) SEMICOLON. { printf("gop_idle_timeout_default\n"); }
gop_idle_timeout_default ::= .

gop_lifetime_default ::= LIFETIME_KW time_value(B) SEMICOLON. { printf("gop_lifetime_default\n"); }
gop_lifetime_default ::= .

gop_drop_unassigned_default ::= DROP_UNASSIGNED_KW true_false(B) SEMICOLON. { printf("gop_drop_unassigned_default\n"); }
gop_drop_unassigned_default ::= .

gop_tree_mode_default ::= SHOW_TREE_KW gop_tree_mode(B) SEMICOLON. { printf("gop_tree_mode_default\n"); }
gop_tree_mode_default ::= .

gop_show_times_default ::= SHOW_TIMES_KW true_false(B) SEMICOLON. { printf("gop_show_times_default\n"); }
gop_show_times_default ::= .

gog_defaults ::= GOG_KW OPEN_BRACE gog_expiration_default gop_tree_mode_default gog_goptree_default gog_show_times_default CLOSE_BRACE SEMICOLON.
gog_defaults ::= .

gog_expiration_default ::= EXPIRATION_KW time_value(B) SEMICOLON. { printf("gog_expiration_default\n"); }
gog_expiration_default ::= .

gog_goptree_default ::= GOP_TREE_KW gop_tree_type(B) SEMICOLON. { printf("gog_goptree_default\n"); }
gog_goptree_default ::= .

gog_show_times_default ::= SHOW_TIMES_KW true_false(B) SEMICOLON. { printf("gog_show_times_default\n"); }
gog_show_times_default ::= .


/******************************************* TRANSFORM
*/

transform_decl(A) ::= TRANSFORM_KW NAME(B) transform_body(C) SEMICOLON. {
        A = "transform_decl";
}

transform_body(A) ::= OPEN_BRACE transform_statements(B) CLOSE_BRACE. { A = B; }

transform_statements(A) ::= transform_statements(C) transform_statement(B). {
        A = "transform_statements";
}

transform_statements(A) ::= transform_statement(B). { A = B; }

transform_statement(A) ::= transform_match(Match) transform_action(Action) SEMICOLON. {
        A = "transform_statement";
}

transform_match(A) ::= MATCH_KW  match_mode(Mode) avpl(Avpl). {
        A = "transform_match";
}

transform_match(A) ::= . {
        A = "transform_match";
}

transform_action(A) ::= . {
        A = "transform_action";
}
transform_action(A) ::= action_mode(Mode) avpl(Avpl). {
        A = "transform_action";
}

match_mode(A) ::=  . { A = AVPL_STRICT; }
match_mode(A) ::=  STRICT_KW. { A = AVPL_STRICT; }
match_mode(A) ::=  EVERY_KW. { A = AVPL_EVERY; }
match_mode(A) ::=  LOOSE_KW. { A = AVPL_LOOSE; }

action_mode(A) ::= REPLACE_KW. { A = AVPL_REPLACE; }
action_mode(A) ::= INSERT_KW. { A = AVPL_INSERT; }
action_mode(A) ::= . { A = AVPL_INSERT; }

/******************************************* PDU
*/

pdu_decl ::=
        PDU_KW NAME(Name) PROTO_KW field(Field) TRANSPORT_KW proto_stack(Stack)
                OPEN_BRACE
                        payload_statement(Payload)
                        extraction_statements(Extraction)
                        transform_list_statement(Transform)
                        criteria_statement(Criteria)
                        pdu_drop_unassigned_statement(DropUnassigned)
                        discard_pdu_data_statement(DistcardPduData)
                        last_extracted_statement(LastExtracted)
                CLOSE_BRACE SEMICOLON.
{
        printf("pdu_decl\n");
}

payload_statement(A) ::= . { A = 0; }
payload_statement(A) ::= PAYLOAD_KW proto_stack(B) SEMICOLON. { A = B; }

criteria_statement(A) ::= . { A = 0; }
criteria_statement(A) ::= CRITERIA_KW accept_mode(B) match_mode(C) avpl(D) SEMICOLON. {
        A = "criteria_statement";
}

accept_mode(A) ::= . { A = ACCEPT_MODE; }
accept_mode(A) ::= ACCEPT_KW. { A = ACCEPT_MODE; }
accept_mode(A) ::= REJECT_KW. { A = REJECT_MODE; }

extraction_statements(A) ::= extraction_statements(B) extraction_statement(C). { A = B; }
extraction_statements(A) ::= extraction_statement(B). { A = B; }

extraction_statement(A) ::= EXTRACT_KW NAME(NAME) FROM_KW field(FIELD) SEMICOLON. {
        A = "extraction_statement";
}


pdu_drop_unassigned_statement(A) ::= DROP_UNASSIGNED_KW true_false(B) SEMICOLON. { A = B; }
pdu_drop_unassigned_statement(A) ::= . { A = 0; }

discard_pdu_data_statement(A) ::=  DISCARD_PDU_DATA_KW true_false(B) SEMICOLON. { A = B; }
discard_pdu_data_statement(A) ::=  . { A = 0; }

last_extracted_statement(A) ::= LAST_PDU_KW true_false(B) SEMICOLON. { A = B; }
last_extracted_statement(A) ::= . { A = 0; }

proto_stack(A) ::= proto_stack(B) SLASH field(C). {
        A = B;
}

proto_stack(A) ::= field(B). {
        A = "proto_stack";
}

field(A) ::= NAME(B). {
        A = "field";
}

/******************************************* GOP
*/

gop_decl(A) ::= GOP_KW NAME(Name) ON_KW pdu_name(PduName) MATCH_KW avpl(Key) OPEN_BRACE
                gop_start_statement(Start)
                gop_stop_statement(Stop)
                extra_statement(Extra)
                transform_list_statement(Transform)
                gop_expiration_statement(Expiration)
                idle_timeout_statement(IdleTimeout)
                lifetime_statement(Lifetime)
                gop_drop_unassigned_statement(DropUnassigned)
                show_goptree_statement(TreeMode)
                show_times_statement(ShowTimes)
        CLOSE_BRACE SEMICOLON. {
        printf("gop_decl\n");
}

gop_drop_unassigned_statement(A) ::= DROP_UNASSIGNED_KW true_false(B) SEMICOLON. { A = B; }
gop_drop_unassigned_statement(A) ::= . { A = 0; }

gop_start_statement(A) ::= START_KW avpl(B) SEMICOLON. { A = B; }
gop_start_statement(A) ::= . { A = 0; }

gop_stop_statement(A) ::= STOP_KW avpl(B) SEMICOLON. { A = B; }
gop_stop_statement(A) ::= . { A = 0; }

show_goptree_statement(A) ::= SHOW_TREE_KW gop_tree_mode(B) SEMICOLON. { A = B; }
show_goptree_statement(A) ::= . { A = 0; }

show_times_statement(A) ::= SHOW_TIMES_KW true_false(B) SEMICOLON. { A = B; }
show_times_statement(A) ::= . { A = 0; }

gop_expiration_statement(A) ::= EXPIRATION_KW time_value(B) SEMICOLON. { A = B; }
gop_expiration_statement(A) ::= . { A = 0; }

idle_timeout_statement(A) ::= IDLE_TIMEOUT_KW time_value(B) SEMICOLON. { A = B; }
idle_timeout_statement(A) ::= . { A = 0; }

lifetime_statement(A) ::= LIFETIME_KW time_value(B) SEMICOLON. { A = B; }
lifetime_statement(A) ::= . { A = 0; }

gop_tree_mode(A) ::= NO_TREE_KW. { A = (gop_tree_mode_t)GOP_NO_TREE; }
gop_tree_mode(A) ::= PDU_TREE_KW. { A = (gop_tree_mode_t)GOP_PDU_TREE; }
gop_tree_mode(A) ::= FRAME_TREE_KW. { A = (gop_tree_mode_t)GOP_FRAME_TREE; }
gop_tree_mode(A) ::= BASIC_TREE_KW. { A = (gop_tree_mode_t)GOP_BASIC_PDU_TREE; }

true_false(A) ::= TRUE_KW. { A = 1; }
true_false(A) ::= FALSE_KW. { A = 0; }

pdu_name(A) ::= NAME(B). {
        A = 0;
}


time_value(A) ::= FLOATING(B). {
        A = 0.0;
}

time_value(A) ::= INTEGER(B). {
        A = 0.0;
}

/************* GOG
*/

gog_decl ::= GOG_KW NAME(Name) OPEN_BRACE
        gog_key_statements(Keys)
        extra_statement(Extra)
        transform_list_statement(Transforms)
        gog_expiration_statement(Expiration)
        gog_goptree_statement(Tree)
        show_times_statement(ShowTimes)
        CLOSE_BRACE SEMICOLON. {
                printf("gog_decl\n");
}

gog_goptree_statement(A) ::= GOP_TREE_KW gop_tree_type(B) SEMICOLON. { A = B; }
gog_goptree_statement(A) ::= . { A = 0; }

gog_expiration_statement(A) ::= EXPIRATION_KW time_value(B) SEMICOLON. { A = B; }
gog_expiration_statement(A) ::= . { A = 0; }

gop_tree_type(A) ::= NULL_TREE_KW. { A = GOP_NULL_TREE; }
gop_tree_type(A) ::= FULL_TREE_KW. { A = GOP_FULL_TREE; }
gop_tree_type(A) ::= BASIC_TREE_KW. { A = GOP_BASIC_TREE; }

gog_key_statements(A) ::= gog_key_statements(B) gog_key_statement(C). {
        A = B;
}

gog_key_statements(A) ::= gog_key_statement(B). {
        A = NULL;
}


gog_key_statement(A) ::= MEMBER_KW gop_name(B) avpl(C) SEMICOLON. {
        A = C;
}

gop_name(A) ::= NAME(B). {
        A = NULL;
}
/******************************************** GENERAL
*/


extra_statement(A) ::= EXTRA_KW avpl(B) SEMICOLON. { A = B; }
extra_statement(A) ::= . { A = NULL; }

transform_list_statement(A) ::= TRANSFORM_KW transform_list(B) SEMICOLON. { A = B; }
transform_list_statement(A) ::= . { A = NULL; }

transform_list(A) ::= transform_list(B) COMMA transform(C). {
        A = B;
}

transform_list(A) ::= transform(B). {
        A = NULL;
}

transform(A) ::= NAME(B). {
        A = NULL;
}

avpl(A) ::= OPEN_PARENS avps(B) CLOSE_PARENS. { A = B; }
avpl(A) ::= OPEN_PARENS CLOSE_PARENS. { A = NULL; }

avps(A) ::= avps(B) COMMA avp(C). { A = B; }
avps(A) ::= avp(B). { A = NULL; }

avp(A) ::= NAME(B) AVP_OPERATOR(C) value(D). { A = NULL; }
avp(A) ::= NAME(B). { A = NULL; }
avp(A) ::= NAME(B) OPEN_BRACE avp_oneoff(C) CLOSE_BRACE. { A = NULL; }

avp_oneoff(A) ::= avp_oneoff(B) PIPE value(C). { A = NULL; }
avp_oneoff(A) ::= value(B). { A = strdup(B); }

value(A) ::= QUOTED(B). { A = strdup(B); }
value(A) ::= NAME(B). { A = strdup(B); }
value(A) ::= FLOATING(B). { A = strdup(B); }
value(A) ::= INTEGER(B). { A = strdup(B); }
value(A) ::= DOTED_IP(B). { A = strdup(B); }
value(A) ::= COLONIZED(B). { A = NULL; }

_______________________________________________
sqlite-users mailing list
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users