Files
CCU4-firmware/parser.ino
2023-09-11 18:04:36 +02:00

132 lines
2.9 KiB
C++

enum {parser_idle, parser_val, parser_id, parser_sym, parser_spec};
enum {parser_num_pos, parser_num_neg, parser_num_error};
struct {
int nextChar;
byte state;
ulong ident;
long num;
byte numstate;
char symbol;
char quote;
byte valPos;
char value[254];
} parser = {-1};
#define PARSEDEBUG 0
int ParserRd() {
int ch = SerialC.read();
if (PARSEDEBUG && ch > 0) {
Serial.write(ch);
}
return ch;
}
ParserType Parser() {
int ch;
ParserType result = parser_none;
ch = parser.nextChar;
if (ch < 0) {
ch = ParserRd();
}
while (ch >= 0 && result == parser_none) {
switch (parser.state) {
case parser_idle:
if (ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z') {
parser.state = parser_id;
parser.ident = 0;
} else if (ch == '{') {
parser.quote = 1;
} else {
parser.state = parser_sym;
}
break;
case parser_sym:
if (ch != ' ') {
result = parser_symbol;
parser.symbol = ch;
}
parser.state = parser_idle;
ch = ParserRd();
break;
case parser_id:
if (ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z' || ch >= '0' && ch <= '9') {
parser.ident = addCharToC40(parser.ident, ch);
/*
if (parser.pos < sizeof parser.ident - 1) {
parser.ident[parser.pos] = ch;
parser.pos++;
} else {
parser.pos++;
}
*/
ch = ParserRd();
} else {
if (parser.ident >= 64000UL*64000UL) {
result = parser_error;
} else {
// Serial.print("parsed "); Serial.print(parser.ident); Serial.println(c40(parser.ident));
result = parser_ident;
}
if (ch == '=') {
parser.state = parser_val;
parser.valPos = 0;
ch = ParserRd();
} else {
parser.state = parser_idle;
}
/*
if (parser.pos >= sizeof parser.ident) {
result = parser_error;
} else {
parser.ident[parser.pos] = 0;
result = parser_ident;
}
*/
}
break;
case parser_val:
if (ch == '{') {
parser.quote++;
ch = ParserRd();
} else if (ch == '}') {
if (parser.quote > 0) parser.quote--;
ch = ParserRd();
} else if (ch < ' ' || (parser.quote == 0 && ch == ' ')) {
ARRAY(parser.value,parser.valPos) = 0;
parser.quote = 0;
result = parser_value;
parser.state = parser_idle;
} else {
if (parser.valPos < sizeof(parser.value) - 1) {
ARRAY(parser.value,parser.valPos) = ch;
parser.valPos++;
}
ch = ParserRd();
}
}
}
parser.nextChar = ch;
return result;
}
long ParserFixed(byte dig, byte *len) {
return text2fix(parser.value, dig, len);
}
ulong ParserIdent() {
return parser.ident;
}
char *ParserText() {
return parser.value;
}
char ParserSymbol() {
return parser.symbol;
}