mirror of
https://github.com/ksherlock/mpw.git
synced 2024-06-08 02:29:36 +00:00
rewrite trap file parser
This commit is contained in:
parent
e2700665d0
commit
cff61ead03
|
@ -75,8 +75,8 @@ namespace {
|
||||||
ToolMap tbrkMap; // tool breaks.
|
ToolMap tbrkMap; // tool breaks.
|
||||||
|
|
||||||
std::map<std::string, uint32_t> SymbolTable;
|
std::map<std::string, uint32_t> SymbolTable;
|
||||||
|
std::map<std::string, uint16_t> TrapTable;
|
||||||
|
|
||||||
void hexdump(const uint8_t *data, ssize_t size, uint32_t address = 0)
|
void hexdump(const uint8_t *data, ssize_t size, uint32_t address = 0)
|
||||||
{
|
{
|
||||||
const char *HexMap = "0123456789abcdef";
|
const char *HexMap = "0123456789abcdef";
|
||||||
|
@ -952,7 +952,7 @@ void Shell()
|
||||||
// printf("%06x: %s\n", kv.second, kv.first.c_str());
|
// printf("%06x: %s\n", kv.second, kv.first.c_str());
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//SymbolTable = LoadTrapFile(MPW::RootDirPathForFile("Traps.text"));
|
LoadTrapFile(MPW::RootDirPathForFile("Traps.text"), TrapTable);
|
||||||
|
|
||||||
// start it up
|
// start it up
|
||||||
printf("MPW Debugger shell\n\n");
|
printf("MPW Debugger shell\n\n");
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <unordered_map>
|
#include <map>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ struct Token {
|
||||||
|
|
||||||
bool ParseLine(const char *iter, Command *command);
|
bool ParseLine(const char *iter, Command *command);
|
||||||
|
|
||||||
std::unordered_map<std::string, uint32_t> LoadTrapFile(const std::string &path);
|
void LoadTrapFile(const std::string &path, std::map<std::string, uint16_t> &map);
|
||||||
|
|
||||||
uint32_t VariableGet(const std::string &);
|
uint32_t VariableGet(const std::string &);
|
||||||
void VariableSet(const std::string &name, uint32_t value);
|
void VariableSet(const std::string &name, uint32_t value);
|
||||||
|
|
281
bin/loadtrap.rl
281
bin/loadtrap.rl
|
@ -24,150 +24,167 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <unordered_map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
%%{
|
namespace {
|
||||||
|
// private...
|
||||||
machine lexer;
|
%%{
|
||||||
|
|
||||||
|
machine lexer;
|
||||||
|
|
||||||
action error {
|
action addx {
|
||||||
fprintf(stderr, "Invalid line: %d %.*s", line, (int)length, cp);
|
value = (value << 4) + digittoint(fc);
|
||||||
fprintf(stderr, "%s - %x\n", name.c_str(), trap);
|
|
||||||
}
|
|
||||||
|
|
||||||
action addx {
|
|
||||||
trap = (trap << 4) + digittoint(fc);
|
|
||||||
}
|
|
||||||
|
|
||||||
action emplace {
|
|
||||||
|
|
||||||
auto iter = map.find(name);
|
|
||||||
|
|
||||||
if (iter == map.end())
|
|
||||||
{
|
|
||||||
map[std::move(name)] = trap;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
ws = [ \t];
|
||||||
|
|
||||||
|
value =
|
||||||
|
'0x' xdigit+ @addx
|
||||||
|
|
|
||||||
|
'$' xdigit+ @addx
|
||||||
|
|
|
||||||
|
[A-Za-z_] @{ stringValue.push_back(fc); }
|
||||||
|
[A-Za-z0-9_]+ @{ stringValue.push_back(fc); }
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
name =
|
||||||
|
[A-Za-z0-9_]+ @{
|
||||||
|
name.push_back(fc);
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
main :=
|
||||||
|
|
||||||
|
name
|
||||||
|
ws*
|
||||||
|
'='
|
||||||
|
ws*
|
||||||
|
value
|
||||||
|
;
|
||||||
|
|
||||||
|
write data;
|
||||||
|
}%%
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool ParseLine(const char *p, const char *pe, std::map<std::string, uint16_t> &map)
|
||||||
|
{
|
||||||
|
|
||||||
|
// trap = number
|
||||||
|
// or trap = [previously defined trap]
|
||||||
|
|
||||||
|
std::string name;
|
||||||
|
std::string stringValue;
|
||||||
|
uint32_t value;
|
||||||
|
|
||||||
|
value = 0;
|
||||||
|
const char *eof = pe;
|
||||||
|
int cs;
|
||||||
|
|
||||||
|
%%write init;
|
||||||
|
%%write exec;
|
||||||
|
|
||||||
|
if (cs < %%{ write first_final; }%% )
|
||||||
{
|
{
|
||||||
if (iter->second != trap)
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// name lookup
|
||||||
|
if (!stringValue.empty())
|
||||||
|
{
|
||||||
|
auto iter = map.find(stringValue);
|
||||||
|
if (iter == map.end())
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Warning: redefining %s ($%04x -> $%04x)\n",
|
fprintf(stderr, "Undefined trap: %s\n", stringValue.c_str());
|
||||||
name.c_str(),
|
return false;
|
||||||
iter->second,
|
}
|
||||||
trap
|
value = iter->second;
|
||||||
);
|
}
|
||||||
iter->second = trap;
|
|
||||||
|
// if loading globals, wouldn't need to do this...
|
||||||
|
if (value > 0xafff || value < 0xa000)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Invalid trap number: $%04x\n", value);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
map.emplace(name, (uint16_t)value);
|
||||||
|
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Debug {
|
||||||
|
|
||||||
|
void LoadTrapFile(const std::string &path, std::map<std::string, uint16_t> &map)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
fp = fopen(path.c_str(), "r");
|
||||||
|
if (!fp)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Unable to open trap file %s\n", path.c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* getline(3) is 2008 posix. it allocates (and resizes as appropriate)
|
||||||
|
* the buffer.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
char *lineBuffer = NULL;
|
||||||
|
size_t lineSize = 0;
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
char *line;
|
||||||
|
ssize_t length;
|
||||||
|
|
||||||
|
length = getline(&lineBuffer, &lineSize, fp);
|
||||||
|
if (!length) continue; //?
|
||||||
|
if (length < 0) break; // eof or error.
|
||||||
|
|
||||||
|
line = lineBuffer;
|
||||||
|
|
||||||
|
// skip any leading space.
|
||||||
|
while (length && isspace(*line))
|
||||||
|
{
|
||||||
|
++line;
|
||||||
|
--length;
|
||||||
|
}
|
||||||
|
if (!length) continue;
|
||||||
|
|
||||||
|
// comments
|
||||||
|
if (*line == '#') continue;
|
||||||
|
|
||||||
|
|
||||||
|
// strip any trailing space.
|
||||||
|
// (will be \n terminated unless there was no \n)
|
||||||
|
while (length && isspace(line[length - 1]))
|
||||||
|
{
|
||||||
|
line[--length] = 0;
|
||||||
|
}
|
||||||
|
if (!length) continue;
|
||||||
|
|
||||||
|
if (!ParseLine(line, line + length, map))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error in trap definition: %s\n", line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
ws = [ \t];
|
|
||||||
|
|
||||||
|
|
||||||
value =
|
|
||||||
'0x' >{trap = 0; } xdigit+ @addx
|
|
||||||
|
|
|
||||||
'$' >{trap = 0; } xdigit+ @addx
|
|
||||||
# todo -- add identifiers?
|
|
||||||
;
|
|
||||||
|
|
||||||
|
|
||||||
line :=
|
|
||||||
[_A-Za-z][_A-Za-z0-9]* @{
|
|
||||||
name.push_back(fc);
|
|
||||||
}
|
|
||||||
|
|
||||||
ws*
|
|
||||||
'='
|
|
||||||
ws*
|
|
||||||
value
|
|
||||||
'\n' @emplace
|
|
||||||
;
|
|
||||||
|
|
||||||
comment := any* ${ fbreak; };
|
|
||||||
|
|
||||||
main := |*
|
|
||||||
ws; # leading space
|
|
||||||
'\n'; # blank line.
|
|
||||||
'#' => { fgoto comment; };
|
|
||||||
[A-Za-z_] => { fhold; fgoto line; };
|
|
||||||
*|;
|
|
||||||
|
|
||||||
}%%
|
|
||||||
|
|
||||||
namespace Debug {
|
|
||||||
std::unordered_map<std::string, uint32_t> LoadTrapFile(const std::string &path)
|
|
||||||
{
|
|
||||||
%% write data;
|
|
||||||
|
|
||||||
FILE *fp;
|
|
||||||
|
|
||||||
std::unordered_map<std::string, uint32_t> map;
|
|
||||||
|
|
||||||
fp = fopen(path.c_str(), "r");
|
|
||||||
if (!fp)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Unable to open file %s\n", path.c_str());
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
// todo -- consider using the debugger parser? That would allow
|
|
||||||
// full mathematical expressions.
|
|
||||||
|
|
||||||
int line = 0;
|
|
||||||
for(;;)
|
|
||||||
{
|
|
||||||
char *cp;
|
|
||||||
|
|
||||||
size_t length;
|
|
||||||
cp = fgetln(fp, &length);
|
|
||||||
if (!cp) break;
|
|
||||||
++line;
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
while (isspace(*cp) && length)
|
|
||||||
{
|
|
||||||
++cp;
|
|
||||||
length--;
|
|
||||||
}
|
|
||||||
if (!length) continue;
|
|
||||||
#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();
|
|
||||||
//const char *eof = pe;
|
|
||||||
const char *ts;
|
|
||||||
const char *te;
|
|
||||||
|
|
||||||
int cs;
|
|
||||||
int act;
|
|
||||||
|
|
||||||
std::string name;
|
|
||||||
uint32_t trap = 0;
|
|
||||||
|
|
||||||
%% write init;
|
|
||||||
/* ... */
|
|
||||||
%% write exec;
|
|
||||||
|
|
||||||
if (cs == lexer_error)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Bad line: %.*s\n", (int)length, cp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(fp);
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,8 +196,8 @@ int main(int argc, char **argv)
|
||||||
for (int i = 1; i < argc; ++i)
|
for (int i = 1; i < argc; ++i)
|
||||||
{
|
{
|
||||||
std::string f(argv[i]);
|
std::string f(argv[i]);
|
||||||
|
std::map<std::string, uint16_t> map;
|
||||||
auto map = Debug::LoadTrapFile(f);
|
Debug::LoadTrapFile(f, map);
|
||||||
|
|
||||||
for(const auto kv : map)
|
for(const auto kv : map)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue
Block a user