%include { /* busmaster_parser.lemon * * Wiretap Library * Copyright (c) 1998 by Gilbert Ramirez * * Support for Busmaster log file format * Copyright (c) 2019 by Maksim Salau * * SPDX-License-Identifier: GPL-2.0-or-later */ #include "config.h" #include #include #include #include #include "busmaster_priv.h" extern void *BusmasterParserAlloc(void *(*mallocProc)(size_t)); extern void BusmasterParser(void *yyp, int yymajor, token_t yyminor, busmaster_state_t *state); extern void BusmasterParserFree(void *p, void (*freeProc)(void*)); #if defined(BUSMASTER_DEBUG) || defined(BUSMASTER_PARSER_TRACE) extern void BusmasterParserTrace(FILE *TraceFILE, char *zTracePrompt); #undef NDEBUG #endif static void merge_msg_data(msg_data_t *dst, const msg_data_t *a, const msg_data_t *b) { dst->length = a->length + b->length; memcpy(&dst->data[0], &a->data[0], a->length); memcpy(&dst->data[a->length], &b->data[0], b->length); } DIAG_OFF(unreachable-code) } %name BusmasterParser %token_prefix TOKEN_ %token_type { token_t } %token_destructor { (void)state; (void)yypParser; (void)yypminor; } %extra_argument { busmaster_state_t* state } %syntax_error { (void)yypParser; (void)yyminor; #ifdef BUSMASTER_DEBUG const int n = sizeof(yyTokenName) / sizeof(yyTokenName[0]); busmaster_debug_printf("%s: got token: %s\n", G_STRFUNC, yyTokenName[yymajor]); for (int i = 0; i < n; ++i) { int a = yy_find_shift_action((YYCODETYPE)i, yypParser->yytos->stateno); if (a < YYNSTATE + YYNRULE) { busmaster_debug_printf("%s: possible token: %s\n", G_STRFUNC, yyTokenName[i]); } } #endif g_free(state->parse_error); state->entry_type = LOG_ENTRY_ERROR; state->parse_error = g_strdup_printf("Syntax Error"); busmaster_debug_printf("%s: Syntax Error\n", G_STRFUNC); } %parse_failure { g_free(state->parse_error); state->entry_type = LOG_ENTRY_ERROR; state->parse_error = g_strdup("Parse Error"); busmaster_debug_printf("%s: Parse Error\n", G_STRFUNC); } %stack_overflow { g_free(state->parse_error); state->entry_type = LOG_ENTRY_ERROR; state->parse_error = g_strdup("Parser stack overflow"); busmaster_debug_printf("%s: Parser stack overflow\n", G_STRFUNC); } %type msg_time { msg_time_t } %type msg_type { msg_type_t } %type err_msg_type { msg_type_t } %type msg_length { guint } %type msg_id { guint32 } %type ref_date { msg_date_t } %type ref_time { msg_time_t } %type start_time { msg_date_time_t } %type byte { guint8 } %type data { msg_data_t } %type data0 { msg_data_t } %type data1 { msg_data_t } %type data2 { msg_data_t } %type data3 { msg_data_t } %type data4 { msg_data_t } %type data5 { msg_data_t } %type data6 { msg_data_t } %type data7 { msg_data_t } %type data8 { msg_data_t } %type data12 { msg_data_t } %type data16 { msg_data_t } %type data20 { msg_data_t } %type data24 { msg_data_t } %type data32 { msg_data_t } %type data48 { msg_data_t } %type data64 { msg_data_t } %nonassoc INVALID_CHAR . %nonassoc INVALID_NUMBER . %start_symbol entry entry ::= empty_line . entry ::= footer_and_header . entry ::= header . entry ::= footer . entry ::= msg . entry ::= err_msg . entry ::= j1939_msg . empty_line ::= . { busmaster_debug_printf("%s: EMPTY\n", G_STRFUNC); state->entry_type = LOG_ENTRY_EMPTY; } footer_and_header ::= footer ENDL header . { busmaster_debug_printf("%s: FOOTER AND HEADER\n", G_STRFUNC); state->entry_type = LOG_ENTRY_FOOTER_AND_HEADER; } header ::= version ENDL maybe_lines PROTOCOL_TYPE(P) ENDL maybe_lines START_SESSION ENDL maybe_lines start_time(S) ENDL maybe_lines DATA_MODE(D) ENDL maybe_lines TIME_MODE(T) ENDL anything . { busmaster_debug_printf("%s: HEADER\n", G_STRFUNC); state->entry_type = LOG_ENTRY_HEADER; state->header.start_date = S.date; state->header.start_time = S.time; state->header.protocol = (protocol_type_t)P.v0; state->header.data_mode = (data_mode_t)D.v0; state->header.time_mode = (time_mode_t)T.v0; } version ::= HEADER_VER maybe_chars . maybe_chars ::= . maybe_chars ::= maybe_chars HEADER_CHAR . maybe_lines ::= . maybe_lines ::= maybe_lines maybe_chars ENDL . anything ::= . anything ::= anything HEADER_CHAR . anything ::= anything ENDL . start_time(R) ::= START_TIME ref_date(D) ref_time(T) . { R.date = D; R.time = T; } footer ::= end_time ENDL STOP_SESSION . { busmaster_debug_printf("%s: FOOTER\n", G_STRFUNC); state->entry_type = LOG_ENTRY_FOOTER; } end_time ::= END_TIME ref_date ref_time . /*