В настоящее время я реализую оценщик выражений (однострочные выражения, например формулы), основанный на следующем:
- введенное выражение токенизируется для разделения буквенных логических значений, целых чисел, десятичных дробей, строк, функций, идентификаторов (переменных)
- Я реализовал алгоритм Shunting-yard (слегка измененный для обработки функций с переменным числом аргументов), чтобы избавиться от скобок и упорядочить операторы с приличным приоритетом в постфиксном порядке.
- мой маневровый двор просто создает (смоделированную) очередь токенов (с помощью массива мой язык Powerbuilder Classic может определять объекты, но иметь только динамические массивы как собственное хранилище - не истинный список, не словарь), которые я оцениваю последовательно с помощью простая стековая машина
Мой оценщик работает хорошо, но мне все еще не хватает if()
и мне интересно, как поступить.
С моей оценкой постфикса и стекового шунтирующего двора, если я добавлю if()
как другую функцию с истинными и ложными частями, одно if(true, msgbox("ok"), msgbox("not ok"))
сообщение покажет оба сообщения, в то время как я хотел бы показать только одно. Это потому, что когда мне нужно оценить функцию, все ее аргументы уже были оценены и помещены в стек.
Не могли бы вы дать мне способ реализовать if()
это ленивым образом?
Я хотя и рассматривал их как своего рода макрос, но на ранних этапах еще не оценил состояние. Возможно, мне нужно использовать другой вид структуры, кроме очереди, чтобы отдельно хранить условие и выражения «истина / ложь»? На данный момент выражение анализируется перед оценкой, но я также планирую сохранить промежуточное представление как вид предварительно скомпилированного выражения для будущей оценки.
Изменить : после некоторого, хотя по проблеме, я думаю, что я мог бы построить представление моего выражения в виде дерева (AST вместо линейного потока токенов), из которого я мог бы легко игнорировать ту или иную ветвь своего if()
.