Разобрать выражение для его компонентов и подкомпонентов.

Мне нужно разобрать выражение, такое как: neg(and(X,Y))

Мне нужно, чтобы он вышел с машинным кодом абстрактного стека, например, для приведенного выше примера:

LOAD X;
LOAD Y;
EXEC and;
EXEC neg;

Но пока машинный код не является проблемой, как я могу разобрать / разбить мою входную строку выражения на все его подвыражения?

Я попытался найти первую скобку, а затем конкаталировать от нее до последней скобки, но что тогда дает смысл, если у вас есть внутреннее выражение?

код, который я пробовал: (пожалуйста, не очень все еще находится в стадии разработки)

private boolean evaluateExpression(String expression) {

    int brackets = 0;
    int beginIndex = -1;
    int endIndex = -1;

    for (int i = 0; i < expression.length(); i++) {
        if (expression.charAt(i) == '(') {
            brackets++;

            if (brackets == 0) {
                endIndex = i;
                System.out.println("the first expression ends at " + i);
            }
        }
        if (expression.charAt(i) == ')') {
            brackets--;

            if (brackets == 0) {
                endIndex = i;
                System.out.println("the first expression ends at " + i);
            }
        }
    }
    // Check for 1st bracket
    for (int i = 0; i < expression.length(); i++) {
        if (expression.charAt(i) == '(') {
            beginIndex = i;
            break;
        }
    }

    String subExpression = expression.substring(beginIndex, endIndex);
    System.out.println("Sub expression: " + subExpression);

    evaluateExpression(subExpression);

    return false;

}

Я просто ищу базовое решение, оно должно только сделать: и, или, нег

3 ответа

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

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

Одним из существующих Java-инструментов, который делает это (и более), является JavaCC, хотя здесь это может быть излишним.
Еще один алгоритм для анализа предложений с использованием CFG - это CYK, который довольно легко программировать и использовать.


Здесь CFG, представляющий доступные выражения:

S -> or(S,S)
S -> and(S,S)
S -> not(S)
S -> x | for each variable x

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

На самом деле, если вы хотите, чтобы ваш синтаксический анализатор был достаточно сильным, чтобы справляться с большинством случаев, вы хотели бы использовать токенизатор (в java реализован класс токенизатора), чтобы сначала маркировать строку, а затем попытаться распознать каждое выражение, храня операнды и операторы в древовидная структура, затем оцените их рекурсивно.

Если вы хотите иметь дело только с некоторыми простыми ситуациями, не забудьте использовать рекурсию, которая является основной частью ~

Синтаксический анализ подобных вещей обычно выполняется с использованием синтаксических деревьев, с использованием некоторого типа предпочтения порядка операций. Пример того, что вы опубликовали, будет следующим:

Processing items left to right the tree would be populated like this

1arg_fcall(neg)
        2arg_fcall(and)
            Load Y                      
            Load X

Now we can recursively visit this tree bottom to top to get
Load X
Load Y
EXEC and //on X and Y
EXEC neg //on result of and
Другие вопросы по тегам