Closed Niuslar closed 2 years ago
If you want to test the parser you could replace the contents of cpp_link.cpp with this:
/**
* @file cpp_link.cpp
*/
/*
* Created on: Feb 11, 2022
* Author: niuslar
*/
#include "../etl/to_string.h"
#include "CAdcData.h"
#include "CDebugController.h"
#include "CDispatcher.h"
#include "CJsonParser.h"
#include "CUartCom.h"
#include "adc.h"
/** @note: Instantiating classes here means the ctor for each class will run
* before any of the setup code is being executed. Therefore, ctor that
* relies on configured hardware will fail. If class that is meant to run
* hardware is instantiated, then ctor must only do bare essentials. Once
* cpp_main() starts executing relevant classes can call initialisation
* methods that will configure the hardware.
*/
CUartCom g_debug_uart("Main");
CDispatcher g_dispatcher(&g_debug_uart);
CJsonParser g_parser;
/* controllers */
CDebugController g_debug_controller("debug", 100);
#ifdef __cplusplus
extern "C"
{
#endif
void cpp_main()
{
g_debug_uart.init(&huart2);
g_debug_uart.startRx();
while (1)
{
if (g_debug_uart.isDataAvailable())
{
if (g_parser.parse(g_debug_uart.getData()))
{
g_debug_uart.send("Command name: ");
g_debug_uart.send(*g_parser.getName());
g_debug_uart.send("\n");
unsigned int arg_count = g_parser.getArgumentCount();
for (unsigned int i = 0; i < arg_count; i++)
{
g_debug_uart.send("Argument ");
etl::string<10> index;
etl::to_string((i + 1), index);
g_debug_uart.send(index);
g_debug_uart.send(": ");
etl::string<30> argument;
etl::to_string(g_parser[i],
argument,
etl::format_spec().precision(1),
true);
g_debug_uart.send(argument);
g_debug_uart.send("\n");
}
}
else
{
g_debug_uart.send("Could not process command\n");
}
}
}
}
#ifdef __cplusplus
}
#endif
Every time you send a command it send back the command name and arguments if the command could be read. Otherwise it send back an error message.
I rewrote most of the parser. I tried changing the logic behind the getTokens() method to work as a state-centric state machine, but I didn't like it. I still believe it makes more sense to use the current character as the event and change the status based on this.
Regarding the actual parser, I'm not sure it is easy to understand, but I don't think any JSON parser is. I added some references so people can understand better the logic behind it.