Перейти к содержанию
    

Модифицировать парсер скрипта

Я запустил этот парсер. Работает. Но чтоб от него была какая то польза нужно добавить кастомные токены.

Вопрос как.

Скажем в моём скрипте

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

    }
}

 

Изменено пользователем jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

а если посмотреть не в непосредственно парсер и токены (там уже есть токен Sys), а в то как там добавлены вызовы функций open, read, write, close, printf ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

ок. я вызову свою функцию. но опкод нужно как то определить. вообще вызов своей функции в  самом скрипте решил бы все проблемы.

Изменено пользователем jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 minutes ago, _pv said:

строки 23 и 1294

ааа. вот куда нужно добавлять. но у меня в токене зашит и номер датчика - TEMP25. так я знаю к какому датчику обратиться.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...