basic FSM working
This commit is contained in:
parent
76d7c2bc62
commit
7a7204ecf4
55
bin/build.js
55
bin/build.js
@ -6,57 +6,48 @@ const llparse = require('llparse');
|
|||||||
const llparseDot = require('llparse-dot');
|
const llparseDot = require('llparse-dot');
|
||||||
|
|
||||||
const prj = 'vcd_parser';
|
const prj = 'vcd_parser';
|
||||||
|
|
||||||
const p = new llparse.LLParse(prj);
|
const p = new llparse.LLParse(prj);
|
||||||
|
|
||||||
|
// Add custom uint8_t property to the state
|
||||||
|
p.property('i8', 'command');
|
||||||
|
|
||||||
const declaration = p.node('declaration');
|
const declaration = p.node('declaration');
|
||||||
|
const commandSpan = p.span(p.code.span('commandSpan'));
|
||||||
const inDeclaration = p.node('inDeclaration');
|
const inDeclaration = p.node('inDeclaration');
|
||||||
const enddefinitions = p.node('inDeclarationEnd');
|
const enddefinitions = p.node('inDeclarationEnd');
|
||||||
const simulation = p.node('simulation');
|
const simulation = p.node('simulation');
|
||||||
const inSimulation = p.node('inSimulation');
|
const inSimulation = p.node('inSimulation');
|
||||||
|
|
||||||
// Add custom uint8_t property to the state
|
|
||||||
p.property('i8', 'declaration');
|
|
||||||
p.property('i8', 'simulation');
|
|
||||||
|
|
||||||
// Store method inside a custom property
|
|
||||||
const onDeclaration = p.invoke(p.code.store('declaration'), inDeclaration);
|
|
||||||
const onSimulation = p.invoke(p.code.store('simulation'), inSimulation);
|
|
||||||
|
|
||||||
declaration
|
declaration
|
||||||
|
.match([' ', '\n', '\t'], declaration)
|
||||||
.select({
|
.select({
|
||||||
'$comment': 0,
|
'$comment': 1, '$date': 2, '$scope': 3, '$timescale': 4,
|
||||||
'$date': 1,
|
'$upscope': 5, '$var': 6, '$version': 7
|
||||||
'$scope': 2,
|
}, p.invoke(p.code.store('command'), commandSpan.start(inDeclaration)))
|
||||||
'$timescale': 3,
|
.select({
|
||||||
'$upscope': 4,
|
'$enddefinitions': 100
|
||||||
'$var': 5,
|
}, p.invoke(p.code.store('command'), commandSpan.start(enddefinitions)))
|
||||||
'$version': 6
|
.otherwise(p.error(1, 'Expected declaration command'));
|
||||||
}, onDeclaration)
|
|
||||||
.match('$enddefinitions', enddefinitions)
|
|
||||||
.otherwise(p.error(1, 'Expected declaration'));
|
|
||||||
|
|
||||||
inDeclaration
|
inDeclaration
|
||||||
.match('$end', declaration)
|
.match('$end', commandSpan.end(declaration))
|
||||||
.otherwise(p.error(2, 'Expected end of declaration'));
|
.skipTo(inDeclaration);
|
||||||
|
|
||||||
enddefinitions
|
enddefinitions
|
||||||
.match('$end', simulation)
|
.match('$end', commandSpan.end(simulation))
|
||||||
.otherwise(p.error(3, 'Expected end of all declaration'));
|
.skipTo(enddefinitions);
|
||||||
|
|
||||||
simulation
|
simulation
|
||||||
|
.match([' ', '\n', '\t'], simulation)
|
||||||
.select({
|
.select({
|
||||||
'$dumpall': 0,
|
'$dumpall': 101, '$dumpoff': 102, '$dumpon': 103, '$dumpvars': 104,
|
||||||
'$dumpoff': 1,
|
'$comment': 1
|
||||||
'$dumpon': 2,
|
}, p.invoke(p.code.store('command'), commandSpan.start(inSimulation)))
|
||||||
'$dumpvars': 3,
|
.otherwise(p.error(2, 'Expected simulation command'));
|
||||||
'$comment': 4
|
|
||||||
}, onSimulation)
|
|
||||||
.otherwise(p.error(4, 'Expected simulation command'));
|
|
||||||
|
|
||||||
inSimulation
|
inSimulation
|
||||||
.match('$end', simulation)
|
.match('$end', commandSpan.end(simulation))
|
||||||
.otherwise(p.error(5, 'Expected end simulation command'));
|
.skipTo(inSimulation);
|
||||||
|
|
||||||
// Build
|
// Build
|
||||||
|
|
||||||
|
@ -14,6 +14,52 @@ describe('basic', () => {
|
|||||||
console.log(cxt);
|
console.log(cxt);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
it('fail: foo bar', done => {
|
||||||
|
const cxt = lib.init();
|
||||||
|
expect(lib.execute(cxt, ' foo bar ???', '')).to.eq(1);
|
||||||
|
expect(lib.getError(cxt)).to.eq(1);
|
||||||
|
expect(lib.getReason(cxt)).to.eq('Expected declaration command');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
it('$comment', done => {
|
||||||
|
const cxt = lib.init();
|
||||||
|
expect(lib.execute(cxt, ' \n $comment some text $end $comment more text $end ???', '')).to.eq(1);
|
||||||
|
expect(lib.getError(cxt)).to.eq(1);
|
||||||
|
expect(lib.getReason(cxt)).to.eq('Expected declaration command');
|
||||||
|
expect(lib.getCommand(cxt)).to.eq(1);
|
||||||
|
// expect(lib.getErrorPos(cxt)).to.eq('Expected declaration');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
it('$version', done => {
|
||||||
|
const cxt = lib.init();
|
||||||
|
expect(lib.execute(cxt, `
|
||||||
|
$version Generated by VerilatedVcd $end
|
||||||
|
$date Wed Sep 18 22:59:07 2019
|
||||||
|
$end
|
||||||
|
$timescale 1ns $end
|
||||||
|
|
||||||
|
$scope module top $end
|
||||||
|
$var wire 1 "}G clock $end
|
||||||
|
$scope module leaf $end
|
||||||
|
$var wire 64 "}> counter [63:0] $end
|
||||||
|
$upscope $end
|
||||||
|
$upscope $end
|
||||||
|
|
||||||
|
$enddefinitions $end
|
||||||
|
|
||||||
|
#1
|
||||||
|
0"}G
|
||||||
|
#2
|
||||||
|
1"}G
|
||||||
|
#3
|
||||||
|
0"}G
|
||||||
|
|
||||||
|
`, '')).to.eq(2);
|
||||||
|
expect(lib.getError(cxt)).to.eq(2);
|
||||||
|
expect(lib.getReason(cxt)).to.eq('Expected simulation command');
|
||||||
|
expect(lib.getCommand(cxt)).to.eq(100);
|
||||||
|
done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
/* eslint-env mocha */
|
/* eslint-env mocha */
|
||||||
|
53
vcd.c
53
vcd.c
@ -33,7 +33,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define ASSERT_STRING(name, var) \
|
#define ASSERT_STRING(name, var) \
|
||||||
char var[256]; \
|
char var[4096]; \
|
||||||
{ \
|
{ \
|
||||||
napi_value tmp; \
|
napi_value tmp; \
|
||||||
if (napi_coerce_to_string(env, name, &tmp) != napi_ok) { \
|
if (napi_coerce_to_string(env, name, &tmp) != napi_ok) { \
|
||||||
@ -41,7 +41,7 @@
|
|||||||
return 0; \
|
return 0; \
|
||||||
} \
|
} \
|
||||||
size_t result; \
|
size_t result; \
|
||||||
if (napi_get_value_string_latin1(env, tmp, var, 256, &result) != napi_ok) { \
|
if (napi_get_value_string_latin1(env, tmp, var, 4096, &result) != napi_ok) { \
|
||||||
napi_throw(env, name); \
|
napi_throw(env, name); \
|
||||||
return 0; \
|
return 0; \
|
||||||
} \
|
} \
|
||||||
@ -91,10 +91,59 @@ METHOD(execute) {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
METHOD(getError) {
|
||||||
|
ASSERT_ARGC(1)
|
||||||
|
struct vcd_parser_s *state;
|
||||||
|
ASSERT_EXTERNAL(args[0], state)
|
||||||
|
|
||||||
|
napi_value res;
|
||||||
|
ASSERT(res, napi_create_int32(env, state->error, &res))
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(getReason) {
|
||||||
|
ASSERT_ARGC(1)
|
||||||
|
struct vcd_parser_s *state;
|
||||||
|
ASSERT_EXTERNAL(args[0], state)
|
||||||
|
|
||||||
|
napi_value res;
|
||||||
|
ASSERT(res, napi_create_string_utf8(env, state->reason, NAPI_AUTO_LENGTH, &res))
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(getErrorPos) {
|
||||||
|
ASSERT_ARGC(1)
|
||||||
|
struct vcd_parser_s *state;
|
||||||
|
ASSERT_EXTERNAL(args[0], state)
|
||||||
|
|
||||||
|
napi_value res;
|
||||||
|
ASSERT(res, napi_create_int32(env, state->error_pos, &res))
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(getCommand) {
|
||||||
|
ASSERT_ARGC(1)
|
||||||
|
struct vcd_parser_s *state;
|
||||||
|
ASSERT_EXTERNAL(args[0], state)
|
||||||
|
|
||||||
|
napi_value res;
|
||||||
|
ASSERT(res, napi_create_int32(env, state->command, &res))
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
napi_value Init(napi_env env, napi_value exports) {
|
napi_value Init(napi_env env, napi_value exports) {
|
||||||
DECLARE_NAPI_METHOD("init", init)
|
DECLARE_NAPI_METHOD("init", init)
|
||||||
DECLARE_NAPI_METHOD("execute", execute)
|
DECLARE_NAPI_METHOD("execute", execute)
|
||||||
|
DECLARE_NAPI_METHOD("getError", getError)
|
||||||
|
DECLARE_NAPI_METHOD("getReason", getReason)
|
||||||
|
DECLARE_NAPI_METHOD("getErrorPos", getErrorPos)
|
||||||
|
DECLARE_NAPI_METHOD("getCommand", getCommand)
|
||||||
return exports;
|
return exports;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int commandSpan(vcd_parser_t* s, const unsigned char* p, const unsigned char* endp) {
|
||||||
|
printf("%d:%.*s\n", s->command, (int)(endp - p - 4), p);
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
NAPI_MODULE(NODE_GYP_MODULE_NAME, Init)
|
NAPI_MODULE(NODE_GYP_MODULE_NAME, Init)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user