1a56e2a107
We've decided to add a separate notion of a DeviceRole to track attached device roles now. We no longer use the collection of deviceSpecs to track which roles have been attached. Rather, this list will simply collate all known deviceAttachment specs which are expected to be maintained in an attached state. SMO can periodically scan through these and cross-reference this collection with the collection of attachedDeviceRoles. Then it can re-try to attach those which aren't currently attached at any given moment. This will give resilience against device attachment failures or device resets/malfunctions, at runtime.
155 lines
4.2 KiB
Plaintext
155 lines
4.2 KiB
Plaintext
%{
|
|
#include <vector>
|
|
#include <utility>
|
|
#include <string>
|
|
#include <cstring>
|
|
#include <cstdlib>
|
|
#include <stdexcept>
|
|
#include <memory>
|
|
#include <functional>
|
|
#include <user/deviceAttachmentSpec.h>
|
|
#include <deviceManager/deviceManager.h>
|
|
|
|
#ifndef yylex
|
|
/* We use different prefixes for the lexer and parser.
|
|
* * Our lexer's prefix is deviceAttachmentPipeSpecl.
|
|
* * Our parser's prefix is deviceAttachmentPipeSpecp.
|
|
*
|
|
* 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 deviceAttachmentPipeSpecllex
|
|
|
|
#ifdef yytext
|
|
#undef yytext
|
|
#endif
|
|
#define yytext deviceAttachmentPipeSpecltext
|
|
|
|
// 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("deviceAttachmentPipeSpec parser error: ")
|
|
+ std::string(message)
|
|
+ " at token: " + std::string(yytext));
|
|
}
|
|
|
|
%}
|
|
|
|
%union {
|
|
char* str;
|
|
char chr;
|
|
smo::device::DeviceAttachmentSpec* sensorSpec;
|
|
smo::device::InteroceptorDevAttachmentSpec* interoceptorSpec;
|
|
smo::device::ExtrospectorDevAttachmentSpec* 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<smo::device::InteroceptorDevAttachmentSpec>(
|
|
*static_cast<smo::device::InteroceptorDevAttachmentSpec *>($3));
|
|
|
|
spec->sensorType = $1;
|
|
smo::device::DeviceManager::deviceAttachmentSpecs.push_back(spec);
|
|
|
|
delete $3;
|
|
}
|
|
;
|
|
|
|
extrospector_spec:
|
|
KEYWORD_SPECTYPE_EXTROSPECTOR PIPE spec_body {
|
|
auto spec = std::make_shared<smo::device::ExtrospectorDevAttachmentSpec>(
|
|
*static_cast<smo::device::ExtrospectorDevAttachmentSpec *>($3));
|
|
|
|
spec->sensorType = $1;
|
|
smo::device::DeviceManager::deviceAttachmentSpecs.push_back(spec);
|
|
|
|
delete $3;
|
|
}
|
|
;
|
|
|
|
spec_body:
|
|
STRING PIPE STRING PIPE STRING LPAREN opt_params RPAREN PIPE STRING LPAREN opt_params RPAREN PIPE STRING {
|
|
$$ = new smo::device::DeviceAttachmentSpec();
|
|
$$->deviceIdentifier = std::string($1);
|
|
$$->sensorType = '\0'; // This will be set by the parent rule
|
|
$$->implexor = std::string($3);
|
|
$$->api = std::string($5);
|
|
$$->apiParams = std::move(*$7);
|
|
$$->provider = std::string($10);
|
|
$$->providerParams = std::move(*$12);
|
|
$$->deviceSelector = std::string($15);
|
|
delete $7;
|
|
delete $12;
|
|
}
|
|
;
|
|
|
|
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);
|
|
}
|
|
;
|
|
|
|
%%
|