mirror of
https://github.com/ksherlock/mpw.git
synced 2024-12-27 03:30:18 +00:00
fix parser bugs
This commit is contained in:
parent
8c0e3f04ac
commit
98b5455549
@ -11,11 +11,11 @@ add_custom_command(
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT parser.cpp parser.h
|
||||
COMMAND cp "${CMAKE_CURRENT_SOURCE_DIR}/parser.lemon" "parser.lemon"
|
||||
OUTPUT parser.c parser.h
|
||||
COMMAND cp -f "${CMAKE_CURRENT_SOURCE_DIR}/parser.lemon" "parser.lemon"
|
||||
COMMAND lemon parser.lemon
|
||||
COMMAND cp parser.h "${CMAKE_CURRENT_SOURCE_DIR}/"
|
||||
COMMAND cp parser.out "${CMAKE_CURRENT_SOURCE_DIR}/"
|
||||
COMMAND cp -f parser.h "${CMAKE_CURRENT_SOURCE_DIR}/"
|
||||
COMMAND cp -f parser.out "${CMAKE_CURRENT_SOURCE_DIR}/"
|
||||
MAIN_DEPENDENCY parser.lemon
|
||||
DEPENDS commands.h
|
||||
)
|
||||
|
@ -17,6 +17,7 @@ extern "C" {
|
||||
void *ParseAlloc(void *(*mallocProc)(size_t));
|
||||
void ParseFree(void *p, void (*freeProc)(void*));
|
||||
void Parse(void *yyp, int yymajor, uint32_t yyminor, Command *command);
|
||||
void ParseTrace(FILE *TraceFILE, char *zTracePrompt);
|
||||
|
||||
}
|
||||
|
||||
@ -37,7 +38,7 @@ namespace {
|
||||
uint32_t scan10(const char *begin, const char *end)
|
||||
{
|
||||
return std::accumulate(begin, end, 0,
|
||||
[](char c, uint32_t value){
|
||||
[](uint32_t value, char c){
|
||||
return value * 10 + c - '0';
|
||||
});
|
||||
}
|
||||
@ -45,7 +46,7 @@ namespace {
|
||||
uint32_t scan16(const char *begin, const char *end)
|
||||
{
|
||||
return std::accumulate(begin, end, 0,
|
||||
[](char c, uint32_t value){
|
||||
[](uint32_t value, char c){
|
||||
return (value << 4) + tox(c);
|
||||
});
|
||||
}
|
||||
@ -109,6 +110,8 @@ bool ParseLine(const char *iter, Command *command)
|
||||
|
||||
parser = ParseAlloc(malloc);
|
||||
|
||||
//ParseTrace(stdout, "--> ");
|
||||
|
||||
for (;;)
|
||||
{
|
||||
const char *begin = iter;
|
||||
@ -125,42 +128,42 @@ bool ParseLine(const char *iter, Command *command)
|
||||
continue;
|
||||
}
|
||||
|
||||
'>=' { Parse(&parser, tkGTEQ, 0, command); continue; }
|
||||
'>>' { Parse(&parser, tkGTGT, 0, command); continue; }
|
||||
'<=' { Parse(&parser, tkLTEQ, 0, command); continue; }
|
||||
'<<' { Parse(&parser, tkLTLT, 0, command); continue; }
|
||||
'!=' { Parse(&parser, tkBANGEQ, 0, command); continue; }
|
||||
'==' { Parse(&parser, tkEQEQ, 0, command); continue; }
|
||||
'||' { Parse(&parser, tkPIPEPIPE, 0, command); continue; }
|
||||
'&&' { Parse(&parser, tkAMPAMP, 0, command); continue; }
|
||||
'>=' { Parse(parser, tkGTEQ, 0, command); continue; }
|
||||
'>>' { Parse(parser, tkGTGT, 0, command); continue; }
|
||||
'<=' { Parse(parser, tkLTEQ, 0, command); continue; }
|
||||
'<<' { Parse(parser, tkLTLT, 0, command); continue; }
|
||||
'!=' { Parse(parser, tkBANGEQ, 0, command); continue; }
|
||||
'==' { Parse(parser, tkEQEQ, 0, command); continue; }
|
||||
'||' { Parse(parser, tkPIPEPIPE, 0, command); continue; }
|
||||
'&&' { Parse(parser, tkAMPAMP, 0, command); continue; }
|
||||
|
||||
|
||||
'(' { Parse(&parser, tkLPAREN, 0, command); continue; }
|
||||
')' { Parse(&parser, tkRPAREN, 0, command); continue; }
|
||||
'=' { Parse(&parser, tkEQ, 0, command); continue; }
|
||||
'+' { Parse(&parser, tkPLUS, 0, command); continue; }
|
||||
'-' { Parse(&parser, tkMINUS, 0, command); continue; }
|
||||
'*' { Parse(&parser, tkSTAR, 0, command); continue; }
|
||||
'/' { Parse(&parser, tkSLASH, 0, command); continue; }
|
||||
'%' { Parse(&parser, tkPERCENT, 0, command); continue; }
|
||||
'~' { Parse(&parser, tkTILDE, 0, command); continue; }
|
||||
'!' { Parse(&parser, tkBANG, 0, command); continue; }
|
||||
'^' { Parse(&parser, tkCARET, 0, command); continue; }
|
||||
'&' { Parse(&parser, tkAMP, 0, command); continue; }
|
||||
'|' { Parse(&parser, tkPIPE, 0, command); continue; }
|
||||
'<' { Parse(&parser, tkLT, 0, command); continue; }
|
||||
'>' { Parse(&parser, tkGT, 0, command); continue; }
|
||||
'(' { Parse(parser, tkLPAREN, 0, command); continue; }
|
||||
')' { Parse(parser, tkRPAREN, 0, command); continue; }
|
||||
'=' { Parse(parser, tkEQ, 0, command); continue; }
|
||||
'+' { Parse(parser, tkPLUS, 0, command); continue; }
|
||||
'-' { Parse(parser, tkMINUS, 0, command); continue; }
|
||||
'*' { Parse(parser, tkSTAR, 0, command); continue; }
|
||||
'/' { Parse(parser, tkSLASH, 0, command); continue; }
|
||||
'%' { Parse(parser, tkPERCENT, 0, command); continue; }
|
||||
'~' { Parse(parser, tkTILDE, 0, command); continue; }
|
||||
'!' { Parse(parser, tkBANG, 0, command); continue; }
|
||||
'^' { Parse(parser, tkCARET, 0, command); continue; }
|
||||
'&' { Parse(parser, tkAMP, 0, command); continue; }
|
||||
'|' { Parse(parser, tkPIPE, 0, command); continue; }
|
||||
'<' { Parse(parser, tkLT, 0, command); continue; }
|
||||
'>' { Parse(parser, tkGT, 0, command); continue; }
|
||||
|
||||
[0-9]+ {
|
||||
// integer
|
||||
uint32_t data;
|
||||
|
||||
data = std::accumulate(begin, iter, 0,
|
||||
[](char c, uint32_t value){
|
||||
return value * 10 + c - '0';
|
||||
[](uint32_t value, char c){
|
||||
return (value * 10) + c - '0';
|
||||
});
|
||||
|
||||
Parse(&parser, tkINTEGER, data, command);
|
||||
Parse(parser, tkINTEGER, data, command);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -169,11 +172,11 @@ bool ParseLine(const char *iter, Command *command)
|
||||
uint32_t data;
|
||||
|
||||
data = std::accumulate(begin + 1, iter, 0,
|
||||
[](char c, uint32_t value){
|
||||
[](uint32_t value, char c){
|
||||
return (value << 4) + tox(c);
|
||||
}
|
||||
);
|
||||
Parse(&parser, tkINTEGER, data, command);
|
||||
Parse(parser, tkINTEGER, data, command);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -182,11 +185,11 @@ bool ParseLine(const char *iter, Command *command)
|
||||
uint32_t data;
|
||||
|
||||
data = std::accumulate(begin + 2, iter, 0,
|
||||
[](char c, uint32_t value){
|
||||
[](uint32_t value, char c){
|
||||
return (value << 4) + tox(c);
|
||||
}
|
||||
);
|
||||
Parse(&parser, tkINTEGER, data, command);
|
||||
Parse(parser, tkINTEGER, data, command);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -195,12 +198,12 @@ bool ParseLine(const char *iter, Command *command)
|
||||
uint32_t data;
|
||||
|
||||
data = std::accumulate(begin + 1, iter - 1, 0,
|
||||
[](char c, uint32_t value)
|
||||
[](uint32_t value, char c)
|
||||
{
|
||||
return (value << 8) + (unsigned)c;
|
||||
}
|
||||
);
|
||||
Parse(&parser, tkINTEGER, data, command);
|
||||
Parse(parser, tkINTEGER, data, command);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -208,102 +211,108 @@ bool ParseLine(const char *iter, Command *command)
|
||||
'd' [0-7] {
|
||||
// data register
|
||||
uint32_t data = begin[1] - '0';
|
||||
Parse(&parser, tkDREGISTER, data, command);
|
||||
Parse(parser, tkDREGISTER, data, command);
|
||||
continue;
|
||||
}
|
||||
|
||||
'a' [0-7] {
|
||||
// address register
|
||||
uint32_t data = begin[1] - '0';
|
||||
Parse(&parser, tkAREGISTER, data, command);
|
||||
Parse(parser, tkAREGISTER, data, command);
|
||||
continue;
|
||||
}
|
||||
|
||||
'pc' {
|
||||
// program counter...
|
||||
Parse(&parser, tkXREGISTER, 0, command);
|
||||
Parse(parser, tkXREGISTER, 0, command);
|
||||
continue;
|
||||
}
|
||||
|
||||
'csr' {
|
||||
// condition status register.
|
||||
Parse(&parser, tkXREGISTER, 1, command);
|
||||
Parse(parser, tkXREGISTER, 1, command);
|
||||
continue;
|
||||
}
|
||||
|
||||
'sp' {
|
||||
// stack pointer aka a7
|
||||
Parse(&parser, tkAREGISTER, 7, command);
|
||||
Parse(parser, tkAREGISTER, 7, command);
|
||||
continue;
|
||||
}
|
||||
|
||||
'fp' {
|
||||
// frame pointer aka a6
|
||||
Parse(&parser, tkAREGISTER, 6, command);
|
||||
Parse(parser, tkAREGISTER, 6, command);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
'c' | 'continue' {
|
||||
Parse(&parser, tkCONTINUE, 0, command);
|
||||
Parse(parser, tkCONTINUE, 0, command);
|
||||
continue;
|
||||
}
|
||||
|
||||
'hd' | 'dump' {
|
||||
Parse(&parser, tkDUMP, 0, command);
|
||||
Parse(parser, tkDUMP, 0, command);
|
||||
continue;
|
||||
}
|
||||
|
||||
'h' | 'help' {
|
||||
Parse(&parser, tkHELP, 0, command);
|
||||
Parse(parser, tkHELP, 0, command);
|
||||
continue;
|
||||
}
|
||||
|
||||
'n' | 'next' {
|
||||
Parse(&parser, tkNEXT, 0, command);
|
||||
Parse(parser, tkNEXT, 0, command);
|
||||
continue;
|
||||
}
|
||||
|
||||
's' | 'step' {
|
||||
Parse(&parser, tkNEXT, 0, command);
|
||||
Parse(parser, tkNEXT, 0, command);
|
||||
continue;
|
||||
}
|
||||
|
||||
'b' | 'brk' | 'break' {
|
||||
Parse(&parser, tkBREAK, 0, command);
|
||||
Parse(parser, tkBREAK, 0, command);
|
||||
continue;
|
||||
}
|
||||
|
||||
'g' | 'go' {
|
||||
Parse(&parser, tkCONTINUE, 0, command);
|
||||
Parse(parser, tkCONTINUE, 0, command);
|
||||
continue;
|
||||
}
|
||||
|
||||
'p' | 'print' {
|
||||
Parse(parser, tkPRINT, 0, command);
|
||||
continue;
|
||||
}
|
||||
|
||||
'r' | 'run' {
|
||||
Parse(&parser, tkCONTINUE, 0, command);
|
||||
Parse(parser, tkCONTINUE, 0, command);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
';l' | ';list' {
|
||||
Parse(&parser, tkSEMIL, 0, command);
|
||||
Parse(parser, tkSEMIL, 0, command);
|
||||
continue;
|
||||
}
|
||||
|
||||
';h' | ';hd' | ';hexdump' {
|
||||
Parse(&parser, tkSEMIH, 0, command);
|
||||
Parse(parser, tkSEMIH, 0, command);
|
||||
continue;
|
||||
}
|
||||
|
||||
[_A-Za-z][_A-Za-z0-9] + {
|
||||
// identifier. lookup global address, tool number, etc.
|
||||
fprintf(stderr, "illegal identifier: %*.s\n", (int)(iter - begin), begin);
|
||||
fprintf(stderr, "illegal identifier: `%.*s`\n", (int)(iter - begin), begin);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
[\x00] {
|
||||
// eol.
|
||||
Parse(parser, tkEOL, 0, command);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -316,8 +325,8 @@ bool ParseLine(const char *iter, Command *command)
|
||||
|
||||
}
|
||||
|
||||
Parse(&parser, 0, 0, command);
|
||||
ParseFree(&parser, free);
|
||||
Parse(parser, 0, 0, command);
|
||||
ParseFree(parser, free);
|
||||
|
||||
return command->valid;
|
||||
}
|
@ -9,11 +9,23 @@
|
||||
#include <string.h>
|
||||
#include "commands.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
uint32_t cpuGetSR();
|
||||
uint32_t cpuGetPC();
|
||||
uint32_t cpuGetAReg(unsigned);
|
||||
uint32_t cpuGetDReg(unsigned);
|
||||
uint32_t debuggerReadLong(uint32_t);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#undef NDEBUG
|
||||
|
||||
}
|
||||
|
||||
%parse_failure {
|
||||
@ -40,40 +52,34 @@ uint32_t debuggerReadLong(uint32_t);
|
||||
%right BANG TILDE.
|
||||
|
||||
|
||||
stmt ::= expr(a).
|
||||
stmt ::= expr(a) EOL.
|
||||
{
|
||||
/*
|
||||
// print the value.
|
||||
// hex, base 10, signed 16-bit (if appropriate)
|
||||
printf("$%08x - %u", a, a);
|
||||
|
||||
if (a & 0x80000000)
|
||||
printf(" %d", (int32_t)a);
|
||||
|
||||
if ((a & 0xffff8000) == 0x8000)
|
||||
printf(" %h", (int16_t)a);
|
||||
|
||||
printf("\n");
|
||||
*/
|
||||
command->action = Print;
|
||||
command->argc = 1;
|
||||
command->argv[0] = a;
|
||||
}
|
||||
|
||||
stmt ::= BREAK expr(a).
|
||||
stmt ::= PRINT expr(a) EOL.
|
||||
{
|
||||
command->action = Print;
|
||||
command->argc = 1;
|
||||
command->argv[0] = a;
|
||||
}
|
||||
|
||||
stmt ::= BREAK expr(a) EOL.
|
||||
{
|
||||
command->action = Break;
|
||||
command->argc = 1;
|
||||
command->argv[0] = a;
|
||||
}
|
||||
|
||||
stmt ::= CONTINUE.
|
||||
stmt ::= CONTINUE EOL.
|
||||
{
|
||||
command->action = Continue;
|
||||
command->argc = 0;
|
||||
}
|
||||
|
||||
stmt ::= TBREAK expr(a).
|
||||
stmt ::= TBREAK expr(a) EOL.
|
||||
{
|
||||
// negative number = remove it.
|
||||
command->action = TBreak;
|
||||
@ -81,48 +87,41 @@ stmt ::= TBREAK expr(a).
|
||||
command->argv[0] = a;
|
||||
}
|
||||
|
||||
stmt ::= NEXT.
|
||||
stmt ::= NEXT EOL.
|
||||
{
|
||||
command->action = Step;
|
||||
command->argc = 0;
|
||||
}
|
||||
|
||||
stmt ::= NEXT expr(a).
|
||||
stmt ::= NEXT expr(a) EOL.
|
||||
{
|
||||
command->action = Step;
|
||||
command->argc = 1;
|
||||
command->argv[0] = a;
|
||||
}
|
||||
|
||||
stmt ::= PRINT expr(a).
|
||||
{
|
||||
command->action = Print;
|
||||
command->argc = 1;
|
||||
command->argv[0] = a;
|
||||
}
|
||||
|
||||
stmt ::= DUMP expr(a).
|
||||
stmt ::= DUMP expr(a) EOL.
|
||||
{
|
||||
command->action = Dump;
|
||||
command->argc = 1;
|
||||
command->argv[0] = a;
|
||||
}
|
||||
|
||||
stmt ::= LIST expr(a).
|
||||
stmt ::= LIST expr(a) EOL.
|
||||
{
|
||||
command->action = List;
|
||||
command->argc = 1;
|
||||
command->argv[0] = a;
|
||||
}
|
||||
|
||||
stmt ::= expr(a) SEMIL.
|
||||
stmt ::= expr(a) SEMIL EOL.
|
||||
{
|
||||
command->action = List;
|
||||
command->argc = 1;
|
||||
command->argv[0] = a;
|
||||
}
|
||||
|
||||
stmt ::= expr(a) SEMIH.
|
||||
stmt ::= expr(a) SEMIH EOL.
|
||||
{
|
||||
command->action = Dump;
|
||||
command->argc = 1;
|
||||
@ -130,7 +129,7 @@ stmt ::= expr(a) SEMIH.
|
||||
}
|
||||
|
||||
|
||||
stmt ::= DREGISTER(a) EQ expr(b).
|
||||
stmt ::= DREGISTER(a) EQ expr(b) EOL.
|
||||
{
|
||||
command->action = SetDRegister;
|
||||
command->argc = 2;
|
||||
@ -138,7 +137,7 @@ stmt ::= DREGISTER(a) EQ expr(b).
|
||||
command->argv[1] = b;
|
||||
}
|
||||
|
||||
stmt ::= AREGISTER(a) EQ expr(b).
|
||||
stmt ::= AREGISTER(a) EQ expr(b) EOL.
|
||||
{
|
||||
command->action = SetARegister;
|
||||
command->argc = 2;
|
||||
@ -146,7 +145,7 @@ stmt ::= AREGISTER(a) EQ expr(b).
|
||||
command->argv[1] = b;
|
||||
}
|
||||
|
||||
stmt ::= XREGISTER(a) EQ expr(b).
|
||||
stmt ::= XREGISTER(a) EQ expr(b) EOL.
|
||||
{
|
||||
command->action = SetXRegister;
|
||||
command->argc = 2;
|
||||
@ -154,31 +153,31 @@ stmt ::= XREGISTER(a) EQ expr(b).
|
||||
command->argv[1] = b;
|
||||
}
|
||||
|
||||
stmt ::= HELP .
|
||||
stmt ::= HELP EOL.
|
||||
{
|
||||
command->action = Help;
|
||||
command->argc = 0;
|
||||
}
|
||||
|
||||
expr(rhs) ::= unary(a). { rhs = a; }
|
||||
expr(rhs) ::= term(a) PLUS term(b). { rhs = a + b; }
|
||||
expr(rhs) ::= term(a) MINUS term(b). { rhs = a + b; }
|
||||
expr(rhs) ::= term(a) STAR term(b). { rhs = a * b; }
|
||||
expr(rhs) ::= term(a) SLASH term(b). { rhs = a / b; }
|
||||
expr(rhs) ::= term(a) PERCENT term(b). { rhs = a % b; }
|
||||
expr(rhs) ::= term(a) LTLT term(b). { rhs = a << b; }
|
||||
expr(rhs) ::= term(a) GTGT term(b). { rhs = a >> b; }
|
||||
expr(rhs) ::= term(a) LT term(b). { rhs = a < b; }
|
||||
expr(rhs) ::= term(a) LTEQ term(b). { rhs = a <= b; }
|
||||
expr(rhs) ::= term(a) GT term(b). { rhs = a > b; }
|
||||
expr(rhs) ::= term(a) GTEQ term(b). { rhs = a >= b; }
|
||||
expr(rhs) ::= term(a) EQEQ term(b). { rhs = a == b; }
|
||||
expr(rhs) ::= term(a) BANGEQ term(b). { rhs = a != b; }
|
||||
expr(rhs) ::= term(a) AMP term(b). { rhs = a & b; }
|
||||
expr(rhs) ::= term(a) CARET term(b). { rhs = a ^ b; }
|
||||
expr(rhs) ::= term(a) PIPE term(b). { rhs = a | b; }
|
||||
expr(rhs) ::= term(a) AMPAMP term(b). { rhs = a && b; }
|
||||
expr(rhs) ::= term(a) PIPEPIPE term(b). { rhs = a || b; }
|
||||
expr(rhs) ::= expr(a) PLUS expr(b). { rhs = a + b; }
|
||||
expr(rhs) ::= expr(a) MINUS expr(b). { rhs = a - b; }
|
||||
expr(rhs) ::= expr(a) STAR expr(b). { rhs = a * b; }
|
||||
expr(rhs) ::= expr(a) SLASH expr(b). { rhs = a / b; }
|
||||
expr(rhs) ::= expr(a) PERCENT expr(b). { rhs = a % b; }
|
||||
expr(rhs) ::= expr(a) LTLT expr(b). { rhs = a << b; }
|
||||
expr(rhs) ::= expr(a) GTGT expr(b). { rhs = a >> b; }
|
||||
expr(rhs) ::= expr(a) LT expr(b). { rhs = a < b; }
|
||||
expr(rhs) ::= expr(a) LTEQ expr(b). { rhs = a <= b; }
|
||||
expr(rhs) ::= expr(a) GT expr(b). { rhs = a > b; }
|
||||
expr(rhs) ::= expr(a) GTEQ expr(b). { rhs = a >= b; }
|
||||
expr(rhs) ::= expr(a) EQEQ expr(b). { rhs = a == b; }
|
||||
expr(rhs) ::= expr(a) BANGEQ expr(b). { rhs = a != b; }
|
||||
expr(rhs) ::= expr(a) AMP expr(b). { rhs = a & b; }
|
||||
expr(rhs) ::= expr(a) CARET expr(b). { rhs = a ^ b; }
|
||||
expr(rhs) ::= expr(a) PIPE expr(b). { rhs = a | b; }
|
||||
expr(rhs) ::= expr(a) AMPAMP expr(b). { rhs = a && b; }
|
||||
expr(rhs) ::= expr(a) PIPEPIPE expr(b). { rhs = a || b; }
|
||||
|
||||
|
||||
unary(rhs) ::= term(a). { rhs = a; }
|
||||
|
Loading…
Reference in New Issue
Block a user