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; }