Jump to content

    
Sign in to follow this  
jenya7

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

Recommended Posts

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

Вопрос как.

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

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

    }
}

 

Edited by jenya7

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites
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); }

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

Edited by jenya7

Share this post


Link to post
Share on other sites
3 minutes ago, _pv said:

строки 23 и 1294

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

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this