jenya7 0 10 января, 2022 Опубликовано 10 января, 2022 (изменено) · Жалоба Я запустил этот парсер. Работает. Но чтоб от него была какая то польза нужно добавить кастомные токены. Вопрос как. Скажем в моём скрипте IF TEMP1 > 30.5 AND HUM2 > 60 THEN OUT2 = 1 я иду и считываю показания датчиков - темрпературу датчика 1 и влажность датчика 2 switch (type) { case VAR_TYPE_TSENS: val = m_sensor.GetDataByValType(num, SENS_VAL_TYPE_TEMP); break; case VAR_TYPE_HSENS: val = m_sensor.GetDataByValType(num, SENS_VAL_TYPE_HUM); break; } Допустим я добавлю в код int eval() { int op, *tmp; while (1) { op = *pc++; // get next operation code ////////////////////////////////////////////////// else if (op == MALC) { ax = (int)malloc(*sp);} else if (op == MSET) { ax = (int)memset((char *)sp[2], sp[1], *sp);} else if (op == MCMP) { ax = memcmp((char *)sp[2], (char *)sp[1], *sp);} ////////////// MY PART /////////////////////////// else if (op == TEMP) { ax = m_sensor.GetDataByValType(num, SENS_VAL_TYPE_TEMP); } else if (op == HUM) { ax = m_sensor.GetDataByValType(num, SENS_VAL_TYPE_HUM); } } } Но как распарсить мои токены (TEMP, HUM) и где хранить номер датчика (1,2)? Spoiler void next() { char *last_pos; int hash; while (token = *src) { ++src; // parse token here if (token == '\n') { ++line; } else if (token == '#') { // skip macro, because we will not support it while (*src != 0 && *src != '\n') { src++; } } else if ((token >= 'a' && token <= 'z') || (token >= 'A' && token <= 'Z') || (token == '_')) { // parse identifier last_pos = src - 1; hash = token; while ((*src >= 'a' && *src <= 'z') || (*src >= 'A' && *src <= 'Z') || (*src >= '0' && *src <= '9') || (*src == '_')) { hash = hash * 147 + *src; src++; } // look for existing identifier, linear search current_id = symbols; while (current_id[Token]) { if (current_id[Hash] == hash && !memcmp((char *)current_id[Name], last_pos, src - last_pos)) { //found one, return token = current_id[Token]; return; } current_id = current_id + IdSize; } // store new ID current_id[Name] = (int)last_pos; current_id[Hash] = hash; token = current_id[Token] = Id; return; } else if (token >= '0' && token <= '9') { // parse number, three kinds: dec(123) hex(0x123) oct(017) token_val = token - '0'; if (token_val > 0) { // dec, starts with [1-9] while (*src >= '0' && *src <= '9') { token_val = token_val*10 + *src++ - '0'; } } else { // starts with 0 if (*src == 'x' || *src == 'X') { //hex token = *++src; while ((token >= '0' && token <= '9') || (token >= 'a' && token <= 'f') || (token >= 'A' && token <= 'F')) { token_val = token_val * 16 + (token & 15) + (token >= 'A' ? 9 : 0); token = *++src; } } else { // oct while (*src >= '0' && *src <= '7') { token_val = token_val*8 + *src++ - '0'; } } } token = Num; return; } else if (token == '"' || token == '\'') { // parse string literal, currently, the only supported escape // character is '\n', store the string literal into data. last_pos = data; while (*src != 0 && *src != token) { token_val = *src++; if (token_val == '\\') { // escape character token_val = *src++; if (token_val == 'n') { token_val = '\n'; } } if (token == '"') { *data++ = token_val; } } src++; // if it is a single character, return Num token if (token == '"') { token_val = (int)last_pos; } else { token = Num; } return; } else if (token == '/') { if (*src == '/') { // skip comments while (*src != 0 && *src != '\n') { ++src; } } else { // divide operator token = Div; return; } } else if (token == '=') { // parse '==' and '=' if (*src == '=') { src ++; token = Eq; } else { token = Assign; } return; } else if (token == '+') { // parse '+' and '++' if (*src == '+') { src ++; token = Inc; } else { token = Add; } return; } else if (token == '-') { // parse '-' and '--' if (*src == '-') { src ++; token = Dec; } else { token = Sub; } return; } else if (token == '!') { // parse '!=' if (*src == '=') { src++; token = Ne; } return; } else if (token == '<') { // parse '<=', '<<' or '<' if (*src == '=') { src ++; token = Le; } else if (*src == '<') { src ++; token = Shl; } else { token = Lt; } return; } else if (token == '>') { // parse '>=', '>>' or '>' if (*src == '=') { src ++; token = Ge; } else if (*src == '>') { src ++; token = Shr; } else { token = Gt; } return; } else if (token == '|') { // parse '|' or '||' if (*src == '|') { src ++; token = Lor; } else { token = Or; } return; } else if (token == '&') { // parse '&' and '&&' if (*src == '&') { src ++; token = Lan; } else { token = And; } return; } else if (token == '^') { token = Xor; return; } else if (token == '%') { token = Mod; return; } else if (token == '*') { token = Mul; return; } else if (token == '[') { token = Brak; return; } else if (token == '?') { token = Cond; return; } else if (token == '~' || token == ';' || token == '{' || token == '}' || token == '(' || token == ')' || token == ']' || token == ',' || token == ':') { // directly return the character as token; return; } } return; } Вопрос упрощается - как из скрипта вызывать внешние функции? Тогда я могу написать int main() { int sens1_val; int sens2_val; while(1) { sens1_val = m_sensor.GetDataByValType(1, SENS_VAL_TYPE_TEMP); sens2_val = m_sensor.GetDataByValType(2, SENS_VAL_TYPE_HUM); if ( sens1_val > 30.5 && sens2_val > 60) Out(1, true); } } Изменено 10 января, 2022 пользователем jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_pv 52 10 января, 2022 Опубликовано 10 января, 2022 · Жалоба а если посмотреть не в непосредственно парсер и токены (там уже есть токен Sys), а в то как там добавлены вызовы функций open, read, write, close, printf ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 10 января, 2022 Опубликовано 10 января, 2022 (изменено) · Жалоба 1 hour ago, _pv said: а если посмотреть не в непосредственно парсер и токены (там уже есть токен Sys), а в то как там добавлены вызовы функций open, read, write, close, printf ? else if (op == OPEN) { ax = open((char *)sp[1], sp[0]); } else if (op == CLOS) { ax = close(*sp);} else if (op == READ) { ax = read(sp[2], (char *)sp[1], *sp); } ок. я вызову свою функцию. но опкод нужно как то определить. вообще вызов своей функции в самом скрипте решил бы все проблемы. Изменено 10 января, 2022 пользователем jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_pv 52 10 января, 2022 Опубликовано 10 января, 2022 · Жалоба 25 minutes ago, jenya7 said: но опкод нужно как то определить. строки 28 и 1294 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 10 января, 2022 Опубликовано 10 января, 2022 · Жалоба 3 minutes ago, _pv said: строки 23 и 1294 ааа. вот куда нужно добавлять. но у меня в токене зашит и номер датчика - TEMP25. так я знаю к какому датчику обратиться. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться