Каковы различные методы синтаксического анализа строк в Java?[закрыто]

StackOverflow https://stackoverflow.com/questions/2968

  •  08-06-2019
  •  | 
  •  

Вопрос

Для разбора команд проигрывателя я чаще всего использовал расколотый метод разделения строки по разделителям, а затем просто вычислить остальное с помощью ряда ifы или switches.Каковы некоторые различные способы синтаксического анализа строк в Java?

Это было полезно?

Решение

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

  1. Считывается в строке
    • Разделите строку на токены
    • Используйте словарь для преобразования синонимов в общую форму
    • Например, преобразуйте "hit", "punch", "strike" и "kick" в "hit".
    • Выполнять действия на неупорядоченной, всеобъемлющей основе
    • Неупорядоченный - "ударить обезьяну по лицу" - это то же самое, что "лицо в ударе обезьяны".
    • Инклюзивный - Если предполагается, что команда должна быть "ударь обезьяну по лицу", а они выдают "ударь обезьяну", вы должны проверить, скольким командам это соответствует.Если только одна команда, выполните это действие.Возможно, было бы даже хорошей идеей установить приоритеты команд, и даже если бы были совпадения, это позволило бы выполнить главное действие.

Другие советы

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

Я бы посоветовал вам проверить http://www.regular-expressions.info для хорошего ознакомления с регулярными выражениями, а также с конкретными примерами для Java.

Разбор вручную - это очень весело...в самом начале:)

На практике, если команды не очень сложные, вы можете обрабатывать их так же, как те, которые используются в интерпретаторах командной строки.Есть список библиотек, которые вы можете использовать: http://java-source.net/open-source/command-line.Я думаю, вы можете начать с интерфейс apache commons CLI или args4j (использует примечания).Они хорошо документированы и действительно просты в использовании.Они обрабатывают синтаксический анализ автоматически, и единственное, что вам нужно сделать, это прочитать определенные поля в объекте.

Если у вас есть более сложные команды, то, возможно, создание формальной грамматики было бы лучшей идеей.Существует очень хорошая библиотека с графическим редактором, отладчиком и интерпретатором грамматик.Это называется ANTLR (и редактор АНТЛРВоркс) и это бесплатно:) Также есть несколько примеров грамматики и руководств.

Я бы посмотрел на Миграции Java из Зорк, и склоняться к простому Процессор естественного языка (управляется либо токенизацией, либо регулярным выражением), таким как следующее (по этой ссылке):

    public static boolean simpleNLP( String inputline, String keywords[])
    {
        int i;
        int maxToken = keywords.length;
        int to,from;
        if( inputline.length() = inputline.length()) return false; // check for blank and empty lines
        while( to >=0 )
        {
            to = inputline.indexOf(' ',from);
            if( to > 0){
                lexed.addElement(inputline.substring(from,to));
                from = to;
                while( inputline.charAt(from) == ' '
                && from = keywords.length) { status = true; break;}
            }
        }
        return status;
    }

...

Все, что дает программисту повод снова взглянуть на Zork, хорошо в моей книге, просто остерегайтесь грубостей.

...

Сам Sun рекомендует держаться подальше от StringTokenizer и вместо этого использовать метод String.spilt.

Вы также захотите взглянуть на класс Pattern.

Еще один голос за ANTLR /ANTLRWorks.Если вы создадите две версии файла, одну с Java-кодом для фактического выполнения команд, а другую без него (только с грамматикой), то у вас будет исполняемая спецификация языка, которая отлично подходит для тестирования, полезна для документации и значительно экономит время, если вы когда-нибудь решите ее портировать.

Если это делается для анализа командных строк, я бы предложил использовать Интерфейс общего доступа.

Библиотека CLI Apache Commons предоставляет API для обработки интерфейсов командной строки.

Попробуй JavaCC ( Явакк ) генератор синтаксических анализаторов для Java.

У него много функций для интерпретации языков, и он хорошо поддерживается в Eclipse.

@CodingTheWheel Вот ваш код, немного подчищенный и через eclipse (ctrl+сдвиг+f) и вставленный обратно сюда :)

Включая четыре пробела перед каждой строкой.

public static boolean simpleNLP(String inputline, String keywords[]) {
    if (inputline.length() < 1)
        return false;

    List<String> lexed = new ArrayList<String>(); 
    for (String ele : inputline.split(" ")) {
        lexed.add(ele);
    }


    boolean status = false;
    to = 0;
    for (i = 0; i < lexed.size(); i++) {
        String s = (String) lexed.get(i);
        if (s.equalsIgnoreCase(keywords[to])) {
            to++;
            if (to >= keywords.length) {
                status = true;
                break;
            }
        }
    }
    return status;
}

Простой строковый токенизатор пробелов должен работать, но есть действительно много способов, которыми вы могли бы это сделать.

Вот пример использования токенизатора:

String command = "kick person";
StringTokenizer tokens = new StringTokenizer(command);
String action = null;

if (tokens.hasMoreTokens()) {
    action = tokens.nextToken();
}

if (action != null) {
    doCommand(action, tokens);
}

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

Если строка-разделитель для команды всегда является одной и той же строкой или символом (например, ";"), я рекомендую использовать класс StrinkTokenizer:

StringTokenizer

но когда разделитель меняется или является сложным, я рекомендую вам использовать обычные выражения, которые могут использоваться самим классом String, методом split, начиная с 1.4.Он использует класс Pattern из пакета java.util.regex

Узор

Если язык до смерти прост, например, просто

ГЛАГОЛ СУЩЕСТВИТЕЛЬНОЕ

тогда разделение вручную работает хорошо.

Если это сложнее, вам действительно следует присмотреться к такому инструменту, как ANTLR или JavaCC.

У меня есть учебник по ANTLR (v2) по адресу http://javadude.com/articles/antlrtut это даст вам представление о том, как это работает.

Командир кажется, довольно неплохо, хотя мне еще предстоит это протестировать.

Если ваш текст содержит какие-либо разделители, то вы можете split способ.
Если текст содержит неправильные строки, что означает, что в нем другой формат, то вы должны использовать regular expressions.

метод split может разбить строку на массив с указанным выражением подстроки regex.Его аргументы представлены в двух формах, а именно:сплит (String regex) и разделиться (String regex, int limit), который разделился (String regex) на самом деле заключается в вызове split (String regex, int limit) для достижения, предел равен 0.Затем, когда предел> 0 и предел <0 что представляет собой?

Когда jdk объясненный:когда предел> 0 длины подмассива до предела, то есть, если возможно, могут быть лимит -1 подраздел, остающийся в качестве подстроки (за исключением ограничения - 1 раз символ имеет разделенный конец строки);

предел <0 указывает на отсутствие ограничений на длину массива;

предел = 0 конец строки пустая строка будет усечена.StringTokenizer класс создан по соображениям совместимости и является сохраненным устаревшим классом, поэтому мы должны попытаться использовать метод split класса String.обратитесь к Ссылка

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top