



Мне очень нравятся регулярные выражения. Пока командные строки довольно просты, вы можете написать несколько регулярных выражений, для ручного анализа которых может потребоваться несколько страниц кода.
Я бы посоветовал вам проверить http://www.regular-expressions.info, чтобы получить хорошее введение в регулярные выражения, а также конкретные примеры для Java.
@Gaurav Vashishta, регулярные выражения могут быть полезны для лексика, но это только первый шаг в синтаксическом анализе.
Простой строковый токенизатор пробелов должен работать, но есть действительно много способов сделать это.
Вот пример использования токенизатора:
String command = "kick person";
StringTokenizer tokens = new StringTokenizer(command);
String action = null;
if (tokens.hasMoreTokens()) {
action = tokens.nextToken();
}
if (action != null) {
doCommand(action, tokens);
}
Затем токены можно использовать в качестве аргументов. Все это предполагает, что в аргументах не используются пробелы ... поэтому вы можете использовать свой собственный простой механизм синтаксического анализа (например, получение первого пробела и использование текста перед в качестве действия или использование регулярного выражения, если вы не возражаете против speed hit), просто абстрагируйте его, чтобы его можно было использовать где угодно.
Насколько я помню, StringTokenizer устарел и настоятельно рекомендуется НЕ использовать его в документах JDK.
Я бы посмотрел на Миграции 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, хорошо в моей книге, только берегитесь Груза.
...
Я предполагаю, что вы пытаетесь сделать командный интерфейс как можно более щадящим. Если это так, я предлагаю вам использовать алгоритм, подобный этому:
@CodingTheWheel Вот ваш код, немного очистить и пройти через eclipse (ctrl + shift + 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 для команды всегда является той же String или char (например, ";") y рекомендуется использовать класс StrinkTokenizer:
но когда разделитель меняется или является сложным, рекомендуется использовать обычные выражения, которые могут использоваться самим классом String, метод split, начиная с версии 1.4. Он использует класс Pattern из пакета java.util.regex
Сама Sun рекомендует держаться подальше от StringTokenizer и вместо этого использовать метод String.split.
Вы также захотите взглянуть на класс Pattern.
Парсить вручную очень весело ... вначале :)
На практике, если команды не очень сложные, вы можете обрабатывать их так же, как те, которые используются в интерпретаторах командной строки. Вот список библиотек, которые вы можете использовать: http://java-source.net/open-source/command-line. Думаю, можно начать с Apache Commons CLI или args4j (использует аннотации). Они хорошо документированы и действительно просты в использовании. Они обрабатывают синтаксический анализ автоматически, и единственное, что вам нужно сделать, это прочитать определенные поля в объекте.
Если у вас есть более сложные команды, возможно, лучше будет создать формальную грамматику. Есть очень хорошая библиотека с графическим редактором, отладчиком и интерпретатором грамматик. Он называется ANTLR (и редактор ANTLRWorks), и он бесплатный :) Есть также несколько примеров грамматик и учебных пособий.
Если это нужно для синтаксического анализа командных строк, я бы предложил использовать Commons Cli.
The Apache Commons CLI library provides an API for processing command line interfaces.
Еще одно голосование за ANTLR / ANTLRWorks. Если вы создадите две версии файла, одну с кодом Java для фактического выполнения команд, а другую без (только с грамматикой), то у вас будет исполняемая спецификация языка, которая отлично подходит для тестирования и является благом для документации. , и сэкономит много времени, если вы когда-нибудь решите его портировать.
Попробуйте JavaCC генератор парсера для Java.
Он имеет множество функций для интерпретации языков и хорошо поддерживается в Eclipse.
Если язык настолько прост, как
ГЛАГОЛ СУЩЕСТВИТЕЛЬНОЕ
тогда хорошо работает ручное разделение.
Если это более сложно, вам действительно стоит изучить такой инструмент, как ANTLR или JavaCC.
У меня есть руководство по ANTLR (v2) на http://javadude.com/articles/antlrtut, которое даст вам представление о том, как это работает.
JCommander кажется неплохим, хотя я его еще не тестировал.
Если ваш текст содержит некоторые разделители, вы можете использовать метод split.
Если текст содержит неправильные строки, значит в нем другой формат, тогда вы должны использовать regular expressions.
Метод split может разбить строку на массив указанного выражения подстроки regex.
Его аргументы представлены в двух формах, а именно: split (String regex) и split (String regex, int limit), причем разбиение (String regex) фактически выполняется путем вызова split (String regex, int limit) для достижения предел 0. Затем, когда предел> 0 и предел представляет что?
Когда поясняется jdk: когда подматрица предел> 0 имеет длину до предела, то есть, если возможно, может быть подразбиением предел-1, оставаясь как подстрока (за исключением случаев, когда limit-1 раз у символа есть конец разделенной строки);
limit указывает на отсутствие ограничения на длину массива;
limit = 0 конец строки пустая строка будет обрезана.
Класс StringTokenizer предназначен для совместимости и является устаревшим классом, поэтому мы должны попытаться использовать метод разделения класса String.
см. связь
Я попытался отредактировать вопрос, чтобы он не основывался на мнении, но боюсь, что ответы уже слишком самоуверенны.