mpw/bin/loadtrap.rl

171 lines
2.4 KiB
Plaintext
Raw Normal View History

2013-07-08 03:39:53 +00:00
#include <unordered_map>
#include <string>
#include <cstdio>
%%{
2013-07-14 18:34:16 +00:00
machine lexer;
2013-07-08 03:39:53 +00:00
action error {
fprintf(stderr, "Invalid line: %d %.*s", line, (int)length, cp);
fprintf(stderr, "%s - %x\n", name.c_str(), trap);
}
2013-07-14 18:34:16 +00:00
action addx {
trap = (trap << 4) + digittoint(fc);
}
action emplace {
auto iter = map.find(name);
2013-07-14 19:17:59 +00:00
if (iter == map.end())
{
map[std::move(name)] = trap;
}
else
2013-07-14 18:34:16 +00:00
{
2013-07-14 19:17:59 +00:00
if (iter->second != trap)
{
fprintf(stderr, "Warning: redefining %s ($%04x -> $%04x)\n",
name.c_str(),
iter->second,
trap
2013-07-14 18:34:16 +00:00
);
2013-07-14 19:17:59 +00:00
iter->second = trap;
}
2013-07-14 18:34:16 +00:00
}
}
ws = [ \t];
value =
'0x' >{trap = 0; } xdigit+ @addx
|
'$' >{trap = 0; } xdigit+ @addx
# todo -- add identifiers?
;
line :=
2013-07-08 03:39:53 +00:00
[_A-Za-z][_A-Za-z0-9]* @{
name.push_back(fc);
}
2013-07-14 18:34:16 +00:00
ws*
2013-07-08 03:39:53 +00:00
'='
2013-07-14 18:34:16 +00:00
ws*
value
'\n' @emplace
;
2013-07-08 03:39:53 +00:00
2013-07-14 18:34:16 +00:00
comment := any* ${ fbreak; };
main := |*
ws; # leading space
'\n'; # blank line.
'#' => { fgoto comment; };
[A-Za-z_] => { fhold; fgoto line; };
*|;
2013-07-08 03:39:53 +00:00
}%%
namespace Debug {
2013-07-14 18:34:16 +00:00
std::unordered_map<std::string, uint32_t> LoadTrapFile(const std::string &path)
2013-07-08 03:39:53 +00:00
{
2013-07-14 18:34:16 +00:00
%% write data;
2013-07-08 03:39:53 +00:00
FILE *fp;
2013-07-14 18:34:16 +00:00
std::unordered_map<std::string, uint32_t> map;
2013-07-08 03:39:53 +00:00
fp = fopen(path.c_str(), "r");
if (!fp)
{
fprintf(stderr, "Unable to open file %s\n", path.c_str());
return map;
}
2013-07-14 18:34:16 +00:00
// todo -- consider using the debugger parser? That would allow
// full mathematical expressions.
2013-07-08 03:39:53 +00:00
int line = 0;
for(;;)
{
char *cp;
size_t length;
cp = fgetln(fp, &length);
if (!cp) break;
++line;
2013-07-14 18:34:16 +00:00
#if 0
2013-07-08 03:39:53 +00:00
while (isspace(*cp) && length)
{
++cp;
length--;
}
if (!length) continue;
2013-07-14 18:34:16 +00:00
#endif
while (length && isspace(cp[length - 1]))
length--;
if (!length) continue;
std::string buffer(cp, cp + length);
buffer.push_back('\n');
const char *p = buffer.c_str();
const char *pe = p + buffer.length();
2013-07-14 19:17:59 +00:00
//const char *eof = pe;
2013-07-14 18:34:16 +00:00
const char *ts;
const char *te;
2013-07-08 03:39:53 +00:00
int cs;
2013-07-14 18:34:16 +00:00
int act;
2013-07-08 03:39:53 +00:00
std::string name;
2013-07-14 18:34:16 +00:00
uint32_t trap = 0;
2013-07-08 03:39:53 +00:00
%% write init;
/* ... */
%% write exec;
2013-07-14 18:34:16 +00:00
if (cs == lexer_error)
{
fprintf(stderr, "Bad line: %.*s\n", (int)length, cp);
}
2013-07-08 03:39:53 +00:00
}
fclose(fp);
return map;
}
}
2013-07-14 18:34:16 +00:00
#ifdef TEST
int main(int argc, char **argv)
{
for (int i = 1; i < argc; ++i)
{
std::string f(argv[i]);
auto map = Debug::LoadTrapFile(f);
for(const auto kv : map)
{
printf("%s -> %04x\n", kv.first.c_str(), kv.second);
}
}
return 0;
}
#endif