Я не уверен, насколько подробно вы интересуетесь, но звучит так, будто вы пытаетесь реализовать парсер.Обычно есть два шага:
Лексер читает текст и преобразует его в токены.Например, он может прочитать «2 + 3 * 2» и преобразовать его в INTEGER
PLUS
INTEGER
STAR
INTEGER
Синтаксический анализатор читает в токенахи пытается сопоставить их с правилами.Например, у вас могут быть следующие правила:
Expr := Sum | Product | INTEGER;
Sum := Expr PLUS Expr;
Product := Expr STAR Expr;
Он читает токены и пытается применить правила таким образом, чтобы правило запуска сопоставлялось с токенами, в которых он прочитан. В этом случае он может выполнить:
Expr := Sum
Expr := Expr PLUS Expr
Expr := INTEGER(2) PLUS Expr
Expr := INTEGER(2) PLUS Product
Expr := INTEGER(2) PLUS Expr STAR Expr
Expr := INTEGER(2) PLUS Integer(3) STAR Expr
Expr := INTEGER(2) PLUS Integer(3) STAR Integer(2)
Существует много типов синтаксических анализаторов.В этом примере я читал слева направо и начинал с начального выражения, работая до тех пор, пока не заменил все токеном, так что это будет LL-парсер .Выполняя эту замену, он может генерировать абстрактное синтаксическое дерево 1023 *, которое представляет данные.Дерево для этого может выглядеть примерно так:
Снимок экрана AST http://so.mrozekma.com/parser1.png
Вы можете видеть, что правило Product является дочерним по отношению к правилу Sum, поэтому в конечном итоге оно произойдет первым: 2 + (3 * 2)
.Если бы выражение было проанализировано по-другому, мы могли бы получить это дерево:
Снимок экрана AST http://so.mrozekma.com/parser2.png
Теперь мы вычисляем (2 + 3) * 2
.Все сводится к тому, как синтаксический анализатор генерирует дерево
Если вы действительно хотите анализировать выражения, скорее всего, вы не хотите писать анализатор вручную.Существуют генераторы синтаксического анализатора , которые принимают конфигурацию (называемую грамматика ), аналогичную той, которую я использовал выше, и генерируют фактический код синтаксического анализатора.Генераторы синтаксических анализаторов позволят вам указать, какое правило должно иметь приоритет, например:
Expr := Sum | Product | INTEGER;
Sum := Expr PLUS Expr; [2]
Product := Expr STAR Expr; [1]
Я пометил правило Product как приоритет 1, а Sum как приоритет 2, поэтому, учитывая выбор, сгенерированный синтаксический анализатор предпочтет Product,Вы также можете создать саму грамматику так, чтобы приоритет был встроенным (это более распространенный подход).Например:
Expr := Sum | INTEGER;
Sum := Expr PLUS Product;
Product := Term STAR INTEGER;
Это приводит к тому, что продукты находятся под суммами в AST.Естественно, эта грамматика очень ограничена (например, она не будет соответствовать 2 * 3 + 2), но можно написать всеобъемлющую грамматику, которая по-прежнему автоматически включает порядок операций