Rename hcore=>smocore
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
# Flex/Bison generated files
|
||||
set(LEX_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/deviceSpecl.cc)
|
||||
set(YACC_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/deviceSpecp.cc)
|
||||
set(YACC_HEADER ${CMAKE_CURRENT_BINARY_DIR}/deviceSpecp.hh)
|
||||
|
||||
# Generate Flex/Bison files using custom commands
|
||||
add_custom_command(
|
||||
OUTPUT ${LEX_OUTPUT}
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/deviceSpecl.ll ${YACC_HEADER}
|
||||
COMMAND ${FLEX_EXECUTABLE} --header-file=${CMAKE_CURRENT_BINARY_DIR}/deviceSpecl.hh -o ${LEX_OUTPUT} ${CMAKE_CURRENT_SOURCE_DIR}/deviceSpecl.ll
|
||||
COMMENT "Generating deviceSpecl.cc from deviceSpecl.ll"
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${YACC_OUTPUT} ${YACC_HEADER}
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/deviceSpecp.yy
|
||||
COMMAND ${BISON_EXECUTABLE} -p deviceSpecp --header=${YACC_HEADER} -o ${YACC_OUTPUT} ${CMAKE_CURRENT_SOURCE_DIR}/deviceSpecp.yy
|
||||
COMMENT "Generating deviceSpecp.cc and deviceSpecp.hh from deviceSpecp.yy"
|
||||
)
|
||||
|
||||
# Device manager library
|
||||
add_library(deviceManager STATIC
|
||||
deviceManager.cpp
|
||||
deviceSpecParser.cpp
|
||||
${LEX_OUTPUT}
|
||||
${YACC_OUTPUT}
|
||||
)
|
||||
|
||||
target_include_directories(deviceManager PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
|
||||
@@ -0,0 +1,37 @@
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
#include <memory>
|
||||
#include <opts.h>
|
||||
#include <deviceManager/deviceManager.h>
|
||||
|
||||
namespace hk {
|
||||
namespace device {
|
||||
|
||||
std::vector<std::shared_ptr<InteroceptorDeviceSpec>>
|
||||
DeviceManager::interoceptorDeviceSpecs;
|
||||
std::vector<std::shared_ptr<ExtrospectorDeviceSpec>>
|
||||
DeviceManager::extrospectorDeviceSpecs;
|
||||
std::vector<std::shared_ptr<SenseDeviceSpec>>
|
||||
DeviceManager::senseDeviceSpecs;
|
||||
|
||||
const std::string DeviceManager::stringifyDeviceSpecs(void)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
|
||||
for (const auto& spec : DeviceManager::interoceptorDeviceSpecs) {
|
||||
oss << "Interoceptor " << spec->stringify();
|
||||
}
|
||||
|
||||
for (const auto& spec : DeviceManager::extrospectorDeviceSpecs) {
|
||||
oss << "Extrospector " << spec->stringify();
|
||||
}
|
||||
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
} // namespace device
|
||||
} // namespace hk
|
||||
@@ -0,0 +1,71 @@
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
#include <memory>
|
||||
#include <cstdio>
|
||||
#include <deviceManager/deviceManager.h>
|
||||
#include "deviceSpecp.hh"
|
||||
#include "deviceSpecl.hh"
|
||||
|
||||
namespace hk {
|
||||
namespace device {
|
||||
|
||||
std::string DeviceManager::readDeviceFile(const std::string& filename)
|
||||
{
|
||||
std::ifstream file(filename);
|
||||
if (!file.is_open())
|
||||
{
|
||||
throw std::runtime_error(
|
||||
std::string(__func__) + ": Couldn't open deviceSpec file: "
|
||||
+ filename);
|
||||
}
|
||||
|
||||
std::string content(
|
||||
(std::istreambuf_iterator<char>(file)),
|
||||
std::istreambuf_iterator<char>());
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
void DeviceManager::collateAllDeviceSpecs(void)
|
||||
{
|
||||
OptionParser &options = OptionParser::getOptions();
|
||||
allDeviceSpecs = options.deviceSpecs;
|
||||
|
||||
for (const auto& file : options.deviceSpecFiles)
|
||||
{
|
||||
std::string fileContent = readDeviceFile(file);
|
||||
if (!allDeviceSpecs.empty()) {
|
||||
allDeviceSpecs += "||";
|
||||
}
|
||||
allDeviceSpecs += fileContent;
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceManager::parseAllDeviceSpecs(void)
|
||||
{
|
||||
std::unique_ptr<FILE, decltype(&fclose)> input(
|
||||
fmemopen((void*)allDeviceSpecs.c_str(), allDeviceSpecs.size(), "r"),
|
||||
&fclose);
|
||||
|
||||
if (!input)
|
||||
{
|
||||
throw std::runtime_error(
|
||||
std::string(__func__) + ": Failed to fmemopen() a FILE* for "
|
||||
"parsing device specs");
|
||||
}
|
||||
|
||||
deviceSpeclin = input.get();
|
||||
if (deviceSpecpparse())
|
||||
{
|
||||
throw std::runtime_error(
|
||||
std::string(__func__) + ": Failed to parse device specs. "
|
||||
"Check specs for errors");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace device
|
||||
} // namespace hk
|
||||
@@ -0,0 +1,62 @@
|
||||
%option prefix="deviceSpecl"
|
||||
%option nounput
|
||||
%option noinput
|
||||
%{
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <deviceManager/deviceManager.h>
|
||||
#include "deviceSpecp.hh"
|
||||
%}
|
||||
|
||||
%%
|
||||
"+adev" {
|
||||
deviceSpecplval.chr = yytext[1];
|
||||
return KEYWORD_SPECTYPE_ACTUATOR;
|
||||
}
|
||||
"+edev" {
|
||||
deviceSpecplval.chr = yytext[1];
|
||||
return KEYWORD_SPECTYPE_EXTROSPECTOR;
|
||||
}
|
||||
"+idev" {
|
||||
deviceSpecplval.chr = yytext[1];
|
||||
return KEYWORD_SPECTYPE_INTEROSPECTOR;
|
||||
}
|
||||
"||" { return DOUBLE_PIPE; }
|
||||
"|" { return PIPE; }
|
||||
"(" { return LPAREN; }
|
||||
")" { return RPAREN; }
|
||||
"=" { return EQUALS; }
|
||||
(\\.|[^=\|\(\) \t\r\n])+ {
|
||||
std::string token(yytext);
|
||||
std::string unescaped;
|
||||
unescaped.reserve(token.size());
|
||||
|
||||
for (size_t i = 0; i < token.size(); ++i)
|
||||
{
|
||||
if (token[i] != '\\')
|
||||
{
|
||||
unescaped.push_back(token[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If a backslash is the final char before EOF, just continue so it gets
|
||||
* dropped as a side effect.
|
||||
*/
|
||||
if (i + 1 >= token.size()) { continue; }
|
||||
|
||||
// Else push the char following the backslash.
|
||||
unescaped.push_back(token[++i]);
|
||||
}
|
||||
|
||||
deviceSpecplval.str = strdup(unescaped.c_str());
|
||||
return STRING;
|
||||
}
|
||||
[ \t\r\n]+ { /* ignore all whitespace, including newlines */ }
|
||||
. { return yytext[0]; }
|
||||
%%
|
||||
|
||||
int deviceSpeclwrap(void)
|
||||
{
|
||||
return 1; // Indicate end of input
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
%{
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#include <stdexcept>
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include <user/senseDeviceSpec.h>
|
||||
#include <deviceManager/deviceManager.h>
|
||||
|
||||
#ifndef yylex
|
||||
/* We use different prefixes for the lexer and parser.
|
||||
* * Our lexer's prefix is deviceSpecl.
|
||||
* * Our parser's prefix is deviceSpecp.
|
||||
*
|
||||
* Yacc and Bison don't have a way to handle the scenario where the lexer has
|
||||
* a different prefix from the parser that they generate. They assume that the
|
||||
* lexer must have the same prefix as the parser they generate. So we just use
|
||||
* this #define below to override yacc/bison's presumed prefix for the lexer.
|
||||
*/
|
||||
#error "Yacc should have defined yylex as a preprocessor token, and we need to override it to tell yacc the name of our lex function."
|
||||
#endif
|
||||
#undef yylex
|
||||
#define yylex deviceSpecllex
|
||||
|
||||
#ifdef yytext
|
||||
#undef yytext
|
||||
#endif
|
||||
#define yytext deviceSpecltext
|
||||
|
||||
// Declare the symbols that our lexer will export.
|
||||
int yylex(void);
|
||||
extern char* yytext; // Declare yytext to access the current token text
|
||||
void yyerror(const char *message)
|
||||
{
|
||||
throw std::runtime_error(
|
||||
std::string("deviceSpec parser error: ")
|
||||
+ std::string(message)
|
||||
+ " at token: " + std::string(yytext));
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
%union {
|
||||
char* str;
|
||||
char chr;
|
||||
hk::device::SenseDeviceSpec* sensorSpec;
|
||||
hk::device::InteroceptorDeviceSpec* interoceptorSpec;
|
||||
hk::device::ExtrospectorDeviceSpec* extrospectorSpec;
|
||||
std::vector<std::pair<std::string,std::string>>* paramVector;
|
||||
std::pair<std::string,std::string>* param;
|
||||
}
|
||||
|
||||
%token <str> STRING
|
||||
%token PIPE DOUBLE_PIPE LPAREN RPAREN
|
||||
%token <chr> KEYWORD_SPECTYPE_ACTUATOR
|
||||
%token <chr> KEYWORD_SPECTYPE_EXTROSPECTOR KEYWORD_SPECTYPE_INTEROSPECTOR
|
||||
%token EQUALS // Add new token for '='
|
||||
|
||||
%type <paramVector> params opt_params
|
||||
%type <param> param
|
||||
%type <sensorSpec> spec_body
|
||||
%type <interoceptorSpec> interoceptor_spec
|
||||
%type <extrospectorSpec> extrospector_spec
|
||||
|
||||
%%
|
||||
|
||||
file: /* NOTHING */
|
||||
| sensor_specs
|
||||
;
|
||||
|
||||
sensor_specs:
|
||||
sensor_spec
|
||||
| sensor_specs DOUBLE_PIPE sensor_spec
|
||||
;
|
||||
|
||||
sensor_spec:
|
||||
interoceptor_spec
|
||||
| extrospector_spec
|
||||
;
|
||||
|
||||
interoceptor_spec:
|
||||
KEYWORD_SPECTYPE_INTEROSPECTOR PIPE spec_body {
|
||||
auto spec = std::make_shared<hk::device::InteroceptorDeviceSpec>(
|
||||
*static_cast<hk::device::InteroceptorDeviceSpec *>($3));
|
||||
|
||||
spec->sensorType = $1;
|
||||
hk::device::DeviceManager::interoceptorDeviceSpecs.push_back(spec);
|
||||
hk::device::DeviceManager::senseDeviceSpecs.push_back(spec);
|
||||
|
||||
delete $3;
|
||||
}
|
||||
;
|
||||
|
||||
extrospector_spec:
|
||||
KEYWORD_SPECTYPE_EXTROSPECTOR PIPE spec_body {
|
||||
auto spec = std::make_shared<hk::device::ExtrospectorDeviceSpec>(
|
||||
*static_cast<hk::device::ExtrospectorDeviceSpec *>($3));
|
||||
|
||||
spec->sensorType = $1;
|
||||
hk::device::DeviceManager::extrospectorDeviceSpecs.push_back(spec);
|
||||
hk::device::DeviceManager::senseDeviceSpecs.push_back(spec);
|
||||
|
||||
delete $3;
|
||||
}
|
||||
;
|
||||
|
||||
spec_body:
|
||||
STRING PIPE STRING LPAREN opt_params RPAREN PIPE STRING LPAREN opt_params RPAREN PIPE STRING {
|
||||
$$ = new hk::device::SenseDeviceSpec();
|
||||
$$->sensorType = '\0';
|
||||
$$->implexor = std::string($1);
|
||||
$$->api = std::string($3);
|
||||
$$->apiParams = std::move(*$5);
|
||||
$$->provider = std::string($8);
|
||||
$$->providerParams = std::move(*$10);
|
||||
$$->deviceSelector = std::string($13);
|
||||
delete $5;
|
||||
delete $10;
|
||||
}
|
||||
;
|
||||
|
||||
opt_params:
|
||||
params
|
||||
| /* empty */ { $$ = new std::vector<std::pair<std::string,std::string>>(); }
|
||||
;
|
||||
|
||||
params:
|
||||
param {
|
||||
$$ = new std::vector<std::pair<std::string,std::string>>();
|
||||
$$->push_back(*$1);
|
||||
delete $1;
|
||||
}
|
||||
| params PIPE param {
|
||||
$$ = $1;
|
||||
$$->push_back(*$3);
|
||||
delete $3;
|
||||
}
|
||||
;
|
||||
|
||||
param:
|
||||
STRING {
|
||||
$$ = new std::pair<std::string,std::string>($1, "");
|
||||
}
|
||||
| STRING EQUALS {
|
||||
$$ = new std::pair<std::string,std::string>($1, "");
|
||||
}
|
||||
| STRING EQUALS STRING {
|
||||
$$ = new std::pair<std::string,std::string>($1, $3);
|
||||
}
|
||||
;
|
||||
|
||||
%%
|
||||
Reference in New Issue
Block a user