Просмотр полной версии : парсинг текста или скрипты в боте
Elecktron
15.02.2013, 13:36
дорос мой бот до скриптов, ибо намертво зашитый функционал слишком не гибкий и давно уже не соответствует требованиям...
казалось бы - вполне хватит команд "а ля валкер" - ничего сложного вроде нет, вносим скрипт в Memo и запускаем.. но не тут то было!
в коде реализуем функции типа:
UseItem(id)
UseSkill(id)
MTL(x,y,z)
и дергать будем их из скрипта.
вопрос только в том, как распознать какую функцию и с каким параметром дернуть..
решение вида:
while (i<Memo1->Lines->Count)
{
c = 0;
opr = Memo1->Lines->Strings[i];
while (c<Memo1->Lines->Strings[i].Length())
{
c++;
if (opr[c] != '#')
{
if (opr[c] == 'M' && opr[c+1] == 'T' && opr[c+2] == 'L')
ShowMessage("MTL");
}
else
{
c = Memo1->Lines->Strings[i].Length();
ShowMessage("закоментированная строка");
}
}
i++;
}
действенно, но несколько не изящно и громоздко
когда количество скриптовых команд разрастется до 10+ можно будет в этом коде сломать не только голову...
к тому же могут возникнуть проблемы с параметрами, количество символов в которых может варьироваться.
гуглю не первый день, в выдаче странные результаты, местами мало относящиеся к моей теме.
использовать сторонние библиотеки и движки не вижу смысла, да нет желания прикручивать в Visual C++..
буду признателен за любые идеи и подсказки...
"нюхом чую", что решение где-то рядом, и совсем простое.. :)
n1ghtmare
15.02.2013, 15:39
Это какой язык? Судя по всему это c++ builder?
Zergatul
15.02.2013, 20:02
Можно заюзать простые рег експы для парсинга названия и всех параметров в удобный массив.
Пример на джаваскрипте (можно запустить в консоли браузера):
str = 'someFunc(1, 2, 3, "qq", true)'
str.match('^([a-zA-Z]+)\\((.+)\\)$')
Выдаст: ["someFunc(1, 2, 3, "qq", true)", "someFunc", "1, 2, 3, "qq", true"]
Дальше парсим параметры:
params = '1, 2, 3, "qq", true'
params.match(/([^,]+)+/g)
Результат:
["1", " 2", " 3", " "qq"", " true"]
n1ghtmare
15.02.2013, 21:58
Примерно так, а в памяти хранить пару { "имя в скрипте", указатель на реальную } А вообще я бы посоветовал lua.
Elecktron
15.02.2013, 22:41
Это какой язык? Судя по всему это c++ builder?
зря ты удалил свое сообщение, оно содержало достаточно много полезной информации.
да это c++ builder.
да конечный вариант будет на MS Visual C++
да я прекрасно понимаю что такие конструкции
if (opr[c] == 'M' && opr[c+1] == 'T' && opr[c+2] == 'L')
попадают под классификацию "быдлокод".
иначе бы я не задавал бы здесь вопросов, а сделал бы так и не морочил голову. в некоторых случаях такого более чем достаточно и нет смысла делать иначе.
у функций не переменное количество аргументов, а переменная "длина" параметров - там может передаваться, например, ник персонажа или название итема, и даже координаты могут иметь разную "величину"... :)
C++ не имеет встроенной реализации работы с регулярными выражениями.
поэтому приходится "лепить"
в phx используется Pax Compiler. это избыточно, громоздко и писалось для delphi.
n1ghtmare
15.02.2013, 23:32
зря ты удалил свое сообщение, оно содержало достаточно много полезной информации.
Удалил потому что провтыкал с языком, увидел memo и сразу подумал что это delphi. :)
Но суть та же. Что мешает в builder'e использовать готовый движок (К примеру Lua, я его использую) ? Причем тут visual c++. Ведь движки как правило ничего кроме stl не используют. В билдере какой-то не такой stl?
Кстати никто не заставляет использовать регулярки, хотя тот же boost имеет реализацию регулярок. функция strstr (http://www.cplusplus.com/reference/cstring/strstr/?kw=strstr)
К примеру так:
if (strstr(line, "MTL(") == line) { ... }
Ищем подстроку, и если она находиться в начале строки то ура.
Это не лучший вариант, т.к. в строковых параметрах к примеру может быть название функции ну и т.п.
используй имеющиеся скрипт движки. больше времени потратиш на изобретение велосипедов чем на бота.
велосипеды - путь к более обширному понимаю того, что происходит. самый лучший путь к самообразванию.
Elecktron
19.02.2013, 18:57
велосипеды - путь к более обширному понимаю того, что происходит. самый лучший путь к самообразванию.
чем я собственно и занимаюсь :)
готовые скриптовые движки (типа PaxCompiler) громоздки и избыточны.
да и конкретно Pax не очень хорошо совмещается с MSVC++
у меня уже есть варианты обработки, но пока это обрывки набросков и мыслей у меня в голове...
когда оформится это все в рабочий (или не очень :)) код я обязательно выложу на суд общественности :)
Elecktron
23.02.2013, 04:37
вот что получилось в результате сбора кусочков мыслей и нескольких часов гугления:
while (i<Memo1->Lines->Count)
{
TStringList *WCount = new TStringList();
TSysCharSet Tws,Tcs;
Tcs<<'('<<')'<<','<<' '; // разделители
AnsiString s = Memo1->Lines->Strings[i];
ExtractStrings(Tcs,Tws,s.c_str(),WCount);
if(WCount->Strings[0] == "MTL")
{
ShowMessage("Moving to x:"+ WCount->Strings[1]+" y:"+WCount->Strings[2]+" z:"+WCount->Strings[3]);
}
else
if(WCount->Strings[0] == "UseItem")
{
ShowMessage("Use Item ID:"+ WCount->Strings[1]);
}
else
if(WCount->Strings[0] == "#")
{
ShowMessage("ignored line");
}
else
Label1->Caption = "Expression syntax on line "+IntToStr(i); //тут бы еще допилить прерывание выполнения...
i++;
delete WCount;
}
в бота еще не интегрировал.
нужно будет переписать на MSVC++ (бот на нем :)), добавить функционала и реализовать отправку соответствующих пакетов...
Antharas
23.02.2013, 06:03
Так он скрипт читать будет тупо текст или еще компилировать его в машинный код? Просто интересно, я не очень шарящий)
Elecktron
23.02.2013, 07:18
это не компилятор.
это скриптовый интерпритатор.
есть набор команд которые мы можем использовать: перемещение в точку с координатами, исползование предмета, использование скила, взятие в таргет, "ткнуть" диалог нпс итд итп...
а вот этим командам мы уже передаем свои параметры...
и последовательность мы тоже задаем.
вопрос только в красоте реализации и защищенности от "дурака", но в варианте "для себя" защитой от дурака можно пренебречь - сам сделал - сам себе "дурак" :)
Добавлено через 59 минут
и возвращаясь к вопросу "а что собственно из готового можно использовать?"
мелкое и ненапряжное, без ооп и тому подобных заморочей, понимающее конструкции "if", "for", "goto" итп, и с возможностью прописывания своих функций?
просто я как-то уже искал, и ничего вменяемого не нашел, потому и начал ваять свое...
Elecktron, вот почитай туториал по lex/yacc, думаю собрать простенький скриптовый движок будет не сложно
n1ghtmare
23.02.2013, 14:24
и возвращаясь к вопросу "а что собственно из готового можно использовать?"
мелкое и ненапряжное, без ооп и тому подобных заморочей, понимающее конструкции "if", "for", "goto" итп, и с возможностью прописывания своих функций?
просто я как-то уже искал, и ничего вменяемого не нашел, потому и начал ваять свое...
Уже предлагал тебе Lua, в нем есть таблицы, есть некое подобие ООП, но никто не заставляет тебя его использовать. Регистрируешь нужные функции и вперед.
Elecktron
24.02.2013, 03:03
Elecktron, вот почитай туториал по lex/yacc, думаю собрать простенький скриптовый движок будет не сложно
погуглил, почитал... не помогло.. кроме назначения неясно ничего... :(
Уже предлагал тебе Lua, в нем есть таблицы, есть некое подобие ООП, но никто не заставляет тебя его использовать. Регистрируешь нужные функции и вперед.
а с луа вообще непонятно - как "это" использовать?
можно пример?
ингейм валкер использует int __cdecl _wcsicmp(const wchar_t *,const wchar_t *) в связке if-else для обработки скрипта...
а вот чем он "нарезает" строки я так и не нашел...
насколько я понял, у вас проблема с обработкой строк.
для сишных строк есть набор функций в <string.h> http://www.cplusplus.com/reference/cstring/
для плюсов стоит переходить на <string> http://www.cplusplus.com/reference/string/
все операции (сравнение строк, поиск подстроки) там реализованы.
для вашего случая нужно:
- взять очередную строку
- найти открывающую скобку
все что между началом строки и открывающей скобкой - ваша команда
- найти закрывающую скобку
все что между открывающей и закрывающей - ваши параметры
чтобы не погружаться в работу с памятью ручками - используйте wstring и соответствующие методы - find, substr
для сишных же строк аналогичные функции - strchr/strstr, strcpy
vBulletin® v3.6.11, Copyright ©2000-2024, Jelsoft Enterprises Ltd. Перевод: zCarot