I am playing a bit around with flex and bison in the embedded firmware creation context.
I like to create a commando line interface for my evaluation board. The commands can be send via UART or USB(ACM). That is why the parser and lexer run buffer based as two instances.
The data and processing looks like:
UART -> buffer A[10] <- lexer instance A @ main -> parser instance A -> handler
USB -> buffer B[255] <- lexer instance B @ main -> parser instance B -> handler
The buffers are filled asynchronous by the IOs. To simplify I bought everything down to a main + lexer + parser structure. There is no need for synchronization via UART and main.
My question deals with the setup of fflex and bison. How to set it up, that I can run 2 instances of them, which are buffer based?
I attach my "not working" code as simple example:
- bl_lexer.c - the lexer
- bl_parser.y - the parser
- main.c - the main
- CMakeLists.txt - cmake build
The following code:
bl_lexer.l
%option noyywrap
%option reentrant
%option prefix="bl_"
%{
#include <stdio.h>
#include "bl_parser.h"
%}
%%
[ \t] ; // ignore all whitespace
[0-9]+ {yylval.ival = atoi(yytext); return t_int;}
\n {return t_nl;}
"help" {return t_help;}
"info" {return t_info;}
%%
bl_parser.y
%{
#include <stdio.h>
#include <stdlib.h>
%}
%define api.pure full
%union {
int ival;
}
%token<ival> t_int
%token t_nl
%token t_help
%token t_info
%start commandL
%%
info_cmd: t_info t_nl { printf("info\n");}
;
help_cmd: t_help t_nl { printf("help\n");}
;
num_cmd: t_int t_nl { printf("num: %i \n", $1);}
;
commandL:
| command
;
command: info_cmd |
help_cmd |
num_cmd
;
%%
main.c
#include <stdio.h>
#include "pl_parser.h"
char buf_A[10];
char buf_B[255];
int main() {
??
return 0;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.1)
project(bl_cmdl)
find_package(BISON REQUIRED)
find_package(FLEX REQUIRED)
set(GEN_DIR "${CMAKE_CURRENT_SOURCE_DIR}/generated")
FILE(MAKE_DIRECTORY ${GEN_DIR})
BISON_TARGET(bl_parser ${CMAKE_CURRENT_SOURCE_DIR}/bl_parser.y "${GEN_DIR}/bl_parser.c"
DEFINES_FILE "${GEN_DIR}/bl_parser.h")
FLEX_TARGET(bl_lexer ${CMAKE_CURRENT_SOURCE_DIR}/bl_lexer.l "${GEN_DIR}/bl_lexer.c")
ADD_FLEX_BISON_DEPENDENCY(bl_lexer bl_parser)
add_executable(bl_cmdL_test
main.c
${FLEX_bl_lexer_OUTPUTS}
${BISON_bl_parser_OUTPUTS}
)
target_include_directories(bl_cmdL_test PRIVATE ${GEN_DIR})