132 lines
2.9 KiB
C++
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;
|
|
}
|