Оценка логических выражений в интерпретаторе скриптов

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

Он начинает работать довольно хорошо, однако я дошел до того, что мне нужно оценивать логические выражения, например, в циклах while, if и т. Д.

Мой текущий код токенизирует сценарий и передает логическое выражение функции с именем ProcessExpression(string[] tokens), когда оно встречается. Примером массива токенов может быть:

local.i
<=
local.arrayLength
+
1
&&
(
local.i
<
local.notThis
||
local.i
>
local.notThis
)

Размышляя о том, как выполнить фактическую оценку, я решил начать с замены переменных фактическими значениями, например: local.i станет 0, local.arrayLength станет 16, а local.notThis станет 10.

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

Тем не менее, я как бы не понимаю, стоит ли мне придерживаться этого подхода или нет. Видя, как одно только вычисление постфикса добавит много кода, мне было интересно, есть ли какие-то уловки, о которых я не подумал? Если postfix действительно подходит, могу ли я каким-то образом заставить его обрабатывать логические условия вместе с математическими операторами?

Я делаю это на C #, но, тем не менее, я не хочу использовать внешние библиотеки или какую-то функцию "Eval". Я также не заинтересован в создании грамматики для этого с использованием таких вещей, как ANTLR, поскольку должны быть менее навязчивые способы для чего-то, казалось бы, «простого» в качестве решателя выражений (если это будет термин для этого).


person Lennard Fonteijn    schedule 05.10.2013    source источник
comment
Решатель выражений основан на синтаксическом дереве. Синтаксическое дерево лучше всего получить из строки с помощью грамматики. Не использовать грамматику - почти наверняка не самое мудрое решение, разве что в качестве обучающего упражнения для себя.   -  person Kirk Woll    schedule 05.10.2013
comment
@KirkWoll Если вы знаете, как реализовать простые грамматики, не требуя от меня использования библиотек, таких как ANTLR, я бы с удовольствием прислушался к возможностям!   -  person Lennard Fonteijn    schedule 05.10.2013
comment
Что ж, чтобы усвоить грамматику, вам нужно либо использовать библиотеку, либо вам нужно написать эту библиотеку самостоятельно. В прошлом я использовал иронию для хорошего эффекта, и у этого есть то достоинство, которого у вас нет вообще отказаться от C #. (грамматики определены в самом C #)   -  person Kirk Woll    schedule 05.10.2013
comment
Я боялся, что вы собираетесь это сказать, я надеялся, что смогу решить логические выражения таким же образом, как и с помощью математических операторов (калькулятор постфиксов), поскольку мне кажется, что я должен добавить это независимо от чего-либо. Если нет других способов решения математических выражений, я думаю, что придерживаюсь постфикса как наиболее эффективного решения, не так ли?   -  person Lennard Fonteijn    schedule 05.10.2013
comment
не уверен, что у вас зависает с использованием библиотеки. Вы уже используете библиотеку, известную как .NET framework. Проблемная область преобразования строки в программные конструкции (выражения) является решенной проблемой. (и решение, конечно, грамматики / парсеры и т. д.)   -  person Kirk Woll    schedule 05.10.2013
comment
У меня есть фиксированный список математических и логических операторов, математику можно решить с помощью постфикса, в худшем случае я мог бы решить логические операторы аналогичным образом. Мой вопрос в том, какие еще у меня есть альтернативы, если грамматика одна из таких, это здорово, но я надеюсь найти такую, которая просто не имеет зависимости от библиотеки. Чтобы ответить на ваш вопрос: портативность. Чем меньше библиотек я использую, тем легче будет перенести это обратно на C ++, что и является моим намерением (все обучающие упражнения, а не практические).   -  person Lennard Fonteijn    schedule 05.10.2013
comment
Если бы я использовал грамматику, я бы, вероятно, написал лексер для полного языка сценариев, это не так весело: P   -  person Lennard Fonteijn    schedule 05.10.2013


Ответы (1)


Итак, чтобы ответить на свой вопрос: в итоге я использовал подход калькулятора постфиксов.

Я передаю все токены своему классу ExpressionSolver, он преобразует его из Infix в Postfix, а затем оценивает Postfix. Список операторов также содержит операторы && и || и обрабатывает их соответствующим образом, когда они встречаются.

Я также закончил тем, что сделал простой лексер на основе Regex для токенизации моего ввода после того, что сказал Кирк Уолл. Это, безусловно, значительно упростило мой синтаксический анализ, прежде чем я действительно смогу решить выражение, я использовал для этого следующий ресурс (также см. Мой комментарий там): Лексер для бедняков для C #

person Lennard Fonteijn    schedule 09.10.2013