Commit 83cf5fbb authored by Anders Blomdell's avatar Anders Blomdell
Browse files

Parsing working for first example

parent 8bed28b1
......@@ -8,14 +8,18 @@ struct moberg_config_parser_token;
enum moberg_config_parser_token_kind {
tok_none,
tok_LBRACE = '{',
tok_RBRACE = '}',
tok_LBRACKET = '[',
tok_RBRACKET = ']',
tok_EQUAL = '=',
tok_COLON = ':',
tok_SEMICOLON = ';',
tok_INTEGER = 256,
tok_EOF,
tok_LPAREN,
tok_RPAREN,
tok_LBRACE,
tok_RBRACE,
tok_LBRACKET,
tok_RBRACKET,
tok_EQUAL,
tok_COMMA,
tok_COLON,
tok_SEMICOLON,
tok_INTEGER,
tok_IDENT,
tok_STRING,
};
......
......@@ -4,21 +4,29 @@
#include <moberg_driver.h>
#include <dlfcn.h>
struct moberg_driver *moberg_open_driver(struct moberg_config_parser_ident id)
struct moberg_driver *moberg_driver_open(struct moberg_config_parser_ident id)
{
struct moberg_driver *result = NULL;
char *driver_name = malloc(sizeof("libmoberg_.so") + id.length + 1);
if (!driver_name) { goto out; }
sprintf(driver_name, "libmoberg_%.*s.so", id.length, id.value);
printf("%s", driver_name);
void *handle = dlopen(driver_name, RTLD_LAZY || RTLD_DEEPBIND);
if (! handle) { goto free_driver_name; }
if (! handle) {
fprintf(stderr, "Could not find driver %s\n", driver_name);
goto free_driver_name;
}
struct moberg_driver_module *module =
(struct moberg_driver_module *) dlsym(handle, "moberg_module");
if (! module) { goto dlclose_driver; }
if (! module) {
fprintf(stderr, "No moberg_module in driver %s\n", driver_name);
goto dlclose_driver;
}
result = malloc(sizeof(*result));
if (! result) { goto dlclose_driver; }
if (! result) {
fprintf(stderr, "Could not allocate result for %s\n", driver_name);
goto dlclose_driver;
}
result->handle = handle;
result->module = *module;
goto free_driver_name;
......@@ -31,7 +39,7 @@ out:
return result;
}
void moberg_close_driver(struct moberg_driver *driver)
void moberg_driver_close(struct moberg_driver *driver)
{
dlclose(driver->handle);
free(driver);
......
......@@ -3,13 +3,12 @@
#include <moberg_config_parser.h>
struct moberg_driver_config {
};
struct moberg_driver_device;
struct moberg_driver_map {
};
typedef struct moberg_driver_config (*moberg_driver_parse_config_t)(
typedef struct moberg_driver_device *(*moberg_driver_parse_config_t)(
struct moberg_config_parser_context *context);
typedef struct moberg_driver_map (*moberg_driver_parse_map_t)(
......@@ -24,9 +23,11 @@ struct moberg_driver {
} module;
};
struct moberg_driver *moberg_open_driver(struct moberg_config_parser_ident id);
struct moberg_driver *moberg_driver_open(struct moberg_config_parser_ident id);
void moberg_driver_close(struct moberg_driver *driver);
void moberg_close_driver(struct moberg_driver *driver);
void moberg_driver_device_free(struct moberg_driver_device *device);
#endif
......@@ -22,57 +22,64 @@ static inline int acceptkeyword(context_t *c,
return moberg_config_parser_acceptkeyword(c, keyword);
}
struct moberg_driver_device {
const char *device;
};
static struct moberg_driver_config parse_config(
static struct moberg_driver_device *parse_config(
struct moberg_config_parser_context *c)
{
struct moberg_driver_config result;
token_t t;
printf("PARSE_CONFIG %s\n", __FILE__);
printf("LBRACE %d", acceptsym(c, tok_LBRACE, &t));
struct moberg_driver_device *result = malloc(sizeof *result);
if (! result) {
fprintf(stderr, "Failed to allocate moberg device\n");
goto err;
}
if (! acceptsym(c, tok_LBRACE, NULL)) { goto syntax_err; }
for (;;) {
if (acceptsym(c, tok_RBRACE, NULL)) {
break;
} else if (acceptkeyword(c, "device")) {
token_t device;
if (! acceptsym(c, tok_EQUAL, NULL)) { goto err; }
if (! acceptsym(c, tok_STRING, &device)) { goto err; }
if (! acceptsym(c, tok_SEMICOLON, NULL)) { goto err; }
if (! acceptsym(c, tok_EQUAL, NULL)) { goto syntax_err; }
if (! acceptsym(c, tok_STRING, &device)) { goto syntax_err; }
if (! acceptsym(c, tok_SEMICOLON, NULL)) { goto syntax_err; }
result->device = strndup(device.u.string.value, device.u.string.length);
} else if (acceptkeyword(c, "config")) {
if (! acceptsym(c, tok_EQUAL, NULL)) { goto err; }
if (! acceptsym(c, tok_LBRACKET, NULL)) { goto err; }
if (! acceptsym(c, tok_EQUAL, NULL)) { goto syntax_err; }
if (! acceptsym(c, tok_LBRACKET, NULL)) { goto syntax_err; }
for (;;) {
if (acceptsym(c, tok_RBRACKET, NULL)) {
break;
} else if (acceptsym(c, tok_IDENT, NULL) ||
acceptsym(c, tok_STRING, NULL)) {
} else {
goto err;
goto syntax_err;
}
}
if (! acceptsym(c, tok_SEMICOLON, NULL)) { goto err; }
if (! acceptsym(c, tok_SEMICOLON, NULL)) { goto syntax_err; }
} else if (acceptkeyword(c, "modprobe")) {
if (! acceptsym(c, tok_EQUAL, NULL)) { goto err; }
if (! acceptsym(c, tok_LBRACKET, NULL)) { goto err; }
if (! acceptsym(c, tok_EQUAL, NULL)) { goto syntax_err; }
if (! acceptsym(c, tok_LBRACKET, NULL)) { goto syntax_err; }
for (;;) {
if (acceptsym(c, tok_RBRACKET, NULL)) {
break;
} else if (acceptsym(c, tok_IDENT, NULL) ||
acceptsym(c, tok_STRING, NULL)) {
} else {
goto err;
goto syntax_err;
}
}
if (! acceptsym(c, tok_SEMICOLON, NULL)) { goto err; }
if (! acceptsym(c, tok_SEMICOLON, NULL)) { goto syntax_err; }
} else {
goto err;
goto syntax_err;
}
}
printf("PARSE_CONFIG DONE%s\n", __FILE__);
return result;
err:
syntax_err:
moberg_config_parser_failed(c, stderr);
exit(1);
err:
return NULL;
}
static struct moberg_driver_map parse_map(
......@@ -81,20 +88,26 @@ static struct moberg_driver_map parse_map(
{
struct moberg_driver_map result;
token_t t;
printf("PARSE_MAP %s\n", __FILE__);
if (! acceptkeyword(c, "subdevice") != 0) { goto err; }
if (! acceptsym(c, tok_LBRACKET, NULL)) { goto err; }
if (! acceptsym(c, tok_INTEGER, &t)) { goto err; }
if (! acceptsym(c, tok_RBRACKET, NULL)) { goto err; }
/*
const char *buf = context->buf;
while (*buf && *buf != '}') {
buf++;
if (! acceptsym(c, tok_LBRACE, NULL)) { goto err; }
for (;;) {
token_t subdevice;
if (! acceptkeyword(c, "subdevice") != 0) { goto err; }
if (! acceptsym(c, tok_LBRACKET, NULL)) { goto err; }
if (! acceptsym(c, tok_INTEGER, &subdevice)) { goto err; }
if (! acceptsym(c, tok_RBRACKET, NULL)) { goto err; }
if (acceptkeyword(c, "route")) {
token_t route;
if (! acceptsym(c, tok_INTEGER, &route)) { goto err; }
}
if (! acceptsym(c, tok_LBRACKET, NULL)) { goto err; }
if (! acceptsym(c, tok_INTEGER, NULL)) { goto err; }
if (acceptsym(c, tok_COLON, NULL)) {
if (! acceptsym(c, tok_INTEGER, NULL)) { goto err; }
}
if (! acceptsym(c, tok_RBRACKET, NULL)) { goto err; }
if (! acceptsym(c, tok_COMMA, NULL)) { break; }
}
context->buf = buf + 1;
*/
if (! acceptsym(c, tok_RBRACE, NULL)) { goto err; }
return result;
err:
moberg_config_parser_failed(c, stderr);
......
#include <moberg_config_parser.h>
#include <moberg_driver.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static struct moberg_driver_config parse_config(
struct moberg_config_parser_context *context)
typedef enum moberg_config_parser_token_kind kind_t;
typedef struct moberg_config_parser_token token_t;
typedef struct moberg_config_parser_ident ident_t;
typedef struct moberg_config_parser_context context_t;
static inline int acceptsym(context_t *c,
kind_t kind,
token_t *token)
{
return moberg_config_parser_acceptsym(c, kind, token);
}
static inline int acceptkeyword(context_t *c,
const char *keyword)
{
struct moberg_driver_config result;
return moberg_config_parser_acceptkeyword(c, keyword);
}
struct moberg_driver_device {
const char *device;
int baud;
};
printf("PARSE_CONFIG %s\n", __FILE__);
/*
const char *buf = context->buf;
while (*buf && *buf != '}') {
buf++;
static struct moberg_driver_device *parse_config(
struct moberg_config_parser_context *c)
{
struct moberg_driver_device *result = malloc(sizeof *result);
if (! result) {
fprintf(stderr, "Failed to allocate moberg device\n");
goto err;
}
if (! acceptsym(c, tok_LBRACE, NULL)) { goto syntax_err; }
for (;;) {
if (acceptsym(c, tok_RBRACE, NULL)) {
break;
} else if (acceptkeyword(c, "device")) {
token_t device;
if (! acceptsym(c, tok_EQUAL, NULL)) { goto syntax_err; }
if (! acceptsym(c, tok_STRING, &device)) { goto syntax_err; }
if (! acceptsym(c, tok_SEMICOLON, NULL)) { goto syntax_err; }
result->device = strndup(device.u.string.value, device.u.string.length);
} else if (acceptkeyword(c, "baud")) {
token_t baud;
if (! acceptsym(c, tok_EQUAL, NULL)) { goto syntax_err; }
if (! acceptsym(c, tok_INTEGER, &baud)) { goto syntax_err; }
if (! acceptsym(c, tok_SEMICOLON, NULL)) { goto syntax_err; }
result->baud = baud.u.integer.value;
} else {
goto syntax_err;
}
}
context->buf = buf + 1;
*/
return result;
syntax_err:
moberg_config_parser_failed(c, stderr);
err:
return NULL;
}
static struct moberg_driver_map parse_map(
struct moberg_config_parser_context *context,
struct moberg_config_parser_context *c,
enum moberg_config_parser_token_kind kind)
{
struct moberg_driver_map result;
printf("PARSE_MAP %s\n", __FILE__);
/*
const char *buf = context->buf;
while (*buf && *buf != '}') {
buf++;
if (acceptkeyword(c, "analog_in") ||
acceptkeyword(c, "analog_out") ||
acceptkeyword(c, "digital_in") ||
acceptkeyword(c, "digital_out") ||
acceptkeyword(c, "encoder_in")) {
if (! acceptsym(c, tok_LBRACKET, NULL)) { goto err; }
if (! acceptsym(c, tok_INTEGER, NULL)) { goto err; }
if (acceptsym(c, tok_COLON, NULL)) {
if (! acceptsym(c, tok_INTEGER, NULL)) { goto err; }
}
if (! acceptsym(c, tok_RBRACKET, NULL)) { goto err; }
}
context->buf = buf + 1;
*/
return result;
err:
moberg_config_parser_failed(c, stderr);
exit(1);
}
struct moberg_driver_module moberg_module = {
......
......@@ -27,7 +27,6 @@ static inline int acceptkeyword(context_t *c,
}
#define MAX_EXPECTED 10
static char expected_char[256][2];
typedef struct moberg_config_parser_context {
char *buf; /* Pointer to data to be parsed */
......@@ -41,6 +40,7 @@ typedef struct moberg_config_parser_context {
static const void nextsym_ident(context_t *c)
{
c->token.kind = tok_IDENT;
c->token.u.ident.length = 1;
c->token.u.ident.value = c->p;
c->p++;
......@@ -54,15 +54,9 @@ static const void nextsym_ident(context_t *c)
c->token.u.ident.length++;
break;
default:
goto out;
break;
return;
}
}
out: ;
const char *v = c->token.u.ident.value;
int l = c->token.u.ident.length;
c->token.kind = tok_IDENT;
printf("IDENT: %.*s %d\n", l, v, c->token.kind);
}
static const void nextsym_integer(context_t *c)
......@@ -74,12 +68,10 @@ static const void nextsym_integer(context_t *c)
c->token.u.integer.value += *c->p - '0';
c->p++;
}
printf("INTEGER: %d\n", c->token.u.integer.value);
}
static const void nextsym_string(context_t *c)
{
printf("STTRING");
c->token.kind = tok_STRING;
c->p++;
c->token.u.string.value = c->p;
......@@ -95,7 +87,6 @@ static const void nextsym_string(context_t *c)
}
}
c->p++;
printf("STRING: %.*s\n", c->token.u.string.length, c->token.u.string.value);
}
static int nextsym(context_t *c)
......@@ -103,7 +94,6 @@ static int nextsym(context_t *c)
c->token.kind = tok_none;
while (c->p && *c->p && c->token.kind == tok_none) {
if (c->p[0] == '/' && c->p[1] == '*') {
printf("Skipping COMMENT\n");
/* Skip comment */
c->p += 2;
while (*c->p && (c->p[0] != '*' || c->p[1] != '/')) {
......@@ -120,6 +110,14 @@ static int nextsym(context_t *c)
/* Skip whitespace */
c->p++;
break;
case '(':
c->token.kind = tok_LPAREN;
c->p++;
break;
case ')':
c->token.kind = tok_RPAREN;
c->p++;
break;
case '{':
c->token.kind = tok_LBRACE;
c->p++;
......@@ -140,6 +138,10 @@ static int nextsym(context_t *c)
c->token.kind = tok_EQUAL;
c->p++;
break;
case ',':
c->token.kind = tok_COMMA;
c->p++;
break;
case ':':
c->token.kind = tok_COLON;
c->p++;
......@@ -165,10 +167,10 @@ static int nextsym(context_t *c)
break;
}
}
printf("TOKEN %d %c\n\n", c->token.kind, c->token.kind<255?c->token.kind:' ');
if (c->token.kind != tok_none) {
return 1;
} else {
c->token.kind = tok_EOF;
return 0;
}
}
......@@ -191,7 +193,6 @@ int moberg_config_parser_acceptsym(context_t *c,
token_t *token)
{
if (c->token.kind == kind) {
printf("ACCEPT %d %s", c->token.kind, expected_char[kind]);
if (token) {
*token = c->token;
}
......@@ -203,13 +204,17 @@ int moberg_config_parser_acceptsym(context_t *c,
const char *what = NULL;
switch (kind) {
case tok_none: break;
case tok_EOF: what = "<EOF>"; break;
case tok_LPAREN: what = "("; break;
case tok_RPAREN: what = ")"; break;
case tok_LBRACE: what = "{"; break;
case tok_RBRACE: what = "}"; break;
case tok_LBRACKET: what = "["; break;
case tok_RBRACKET: what = "]"; break;
case tok_EQUAL: what = "="; break;
case tok_COMMA: what = ","; break;
case tok_COLON: what = ":"; break;
case tok_SEMICOLON: what = "y;"; break;
case tok_SEMICOLON: what = ";"; break;
case tok_INTEGER: what = "<INTEGER>"; break;
case tok_IDENT: what = "<IDENT>"; break;
case tok_STRING: what = "<STRING>"; break;
......@@ -219,7 +224,6 @@ int moberg_config_parser_acceptsym(context_t *c,
c->expected.n++;
}
}
printf("REJECT %d (%d)", kind, c->token.kind);
return 0;
}
......@@ -245,25 +249,39 @@ void moberg_config_parser_failed(
FILE *f)
{
fprintf(f, "EXPECTED ");
for (int i = 0 ; i < c->expected.n ; i++) {
fprintf(f, "%s ", c->expected.what[i]);
for (int i = 0 ; i < c->expected.n; i++) {
if (i > 0) {
fprintf(f, " | ");
}
fprintf(f, "'%s'", c->expected.what[i]);
}
const char *what = "";
fprintf(f, "\nGOT: ");
switch (c->token.kind) {
case tok_none: break;
case tok_LBRACE: what = "{"; break;
case tok_RBRACE: what = "}"; break;
case tok_LBRACKET: what = "["; break;
case tok_RBRACKET: what = "]"; break;
case tok_EQUAL: what = "="; break;
case tok_COLON: what = ":"; break;
case tok_SEMICOLON: what = ";"; break;
case tok_INTEGER: what = "<INTEGER>"; break;
case tok_IDENT: what = "<IDENT>"; break;
case tok_STRING: what = "<STRING>"; break;
case tok_none: break;
case tok_EOF: fprintf(f, "<EOF>"); break;
case tok_LPAREN: fprintf(f, "("); break;
case tok_RPAREN: fprintf(f, ")"); break;
case tok_LBRACE: fprintf(f, "{"); break;
case tok_RBRACE: fprintf(f, "}"); break;
case tok_LBRACKET: fprintf(f, "["); break;
case tok_RBRACKET: fprintf(f, "]"); break;
case tok_EQUAL: fprintf(f, "="); break;
case tok_COMMA: fprintf(f, ","); break;
case tok_COLON: fprintf(f, ":"); break;
case tok_SEMICOLON: fprintf(f, ";"); break;
case tok_INTEGER:
fprintf(f, "%d (<INTEGER>)", c->token.u.integer.value);
break;
case tok_IDENT:
fprintf(f, "%.*s (<IDENT>)",
c->token.u.ident.length, c->token.u.ident.value);
break;
case tok_STRING:
fprintf(f, "\"%.*s'\" (<STRING>)",
c->token.u.string.length, c->token.u.string.value);
break;
}
fprintf(f, "\nGOT %s %s\n", what, c->p);
fprintf(f, "\n%s\n", c->p);
}
......@@ -288,7 +306,6 @@ err:
static int parse_map(context_t *c,
struct moberg_driver *driver)
{
printf("parsemap");
if (acceptkeyword(c, "analog_in") ||
acceptkeyword(c, "analog_out") ||
acceptkeyword(c, "digital_in") ||
......@@ -297,7 +314,6 @@ static int parse_map(context_t *c,
if (! parse_map_range(c)) { goto err; }
if (! acceptsym(c, tok_EQUAL, NULL)) { goto err; }
driver->module.parse_map(c, 0);
if (! parse_map_range(c)) { goto err; }
if (! acceptsym(c, tok_SEMICOLON, NULL)) { goto err; }
} else {
goto err;
......@@ -329,36 +345,34 @@ err:
return 0;
}
static int parse_driver(context_t *c,
ident_t name)
{
struct moberg_driver *driver = moberg_open_driver(name);
if (! driver) {
printf("Driver not found\n");
goto err;
} else {
int OK = parse_device(c, driver);
moberg_close_driver(driver);
if (! OK) { goto err; }
}
return 1;
err:
return 0;
}
static int parse_config(context_t *c)
{
for (;;) {
token_t t;
if (acceptsym(c, tok_IDENT, &t)) {
printf("DRIVER=%.*s\n", t.u.ident.length, t.u.ident.value);
if (! parse_driver(c, t.u.ident)) { goto err; }
if (acceptsym(c, tok_EOF, NULL)) {
break;
} else {
token_t t;
struct moberg_driver *driver;
if (! acceptkeyword(c, "driver")) { goto syntax_err; }
if (! acceptsym(c, tok_LPAREN, NULL)) { goto syntax_err; }
if (! acceptsym(c, tok_IDENT, &t)) { goto syntax_err; }
if (! acceptsym(c, tok_RPAREN, NULL)) { goto syntax_err; }
if (! (driver = moberg_driver_open(t.u.ident))) { goto driver_not_found; }
int OK = parse_device(c, driver);
moberg_driver_close(driver);
if (! OK) { goto err; }
}
}
return 1;
syntax_err:
moberg_config_parser_failed(c, stderr);
goto err;
driver_not_found:
fprintf(stderr, "Could not open\n");
goto err;
err:
printf("Failed!!");
exit (1);
return 0;
}
......
comedi {
driver(comedi) {
config {
/* Parsed by parse_config in libmoberg_comedi.so */
device = "/dev/comedi0" ;
......@@ -7,13 +7,13 @@ comedi {
}
/* Moberg mapping[indices] = {driver specific}[indices]
{driver specific} is parsed by parse_map in libmoberg_comedi.so */
map analog_in[0:7] = subdevice[0][0:7] ;
map analog_out[0:1] = subdevice[1][0:1] ;
map digital_in[0] = subdevice[7][15] ;
map digital_in[1] = subdevice[7][2] ;
map digital_out[0:1] = subdevice[7] route 16 [0:1];
map analog_in[0:7] = { subdevice[0][0:7] };
map analog_out[0:1] = { subdevice[1][0:1] };
map digital_in[0:1] = { subdevice[7][15] ,