Я работаю на построение лексического анализатора для вымышленного языка XML-стиля, и я в настоящее время пытаюсь включить следующую лексическую спецификацию в Java код:Использования Regex в лексическом анализаторе (Java)
Name -> Initial Other*
Initial -> Letter | _ | :
Other -> Initial | Digit | - | .
String -> " (Char | ')* " | '(Char | ")* '
Data -> Char+
Char -> Ordinary | Special | Reference
Ordinary -> NOT (< | > | " | ' | &)
Special -> < | > | " | ' | &
Reference -> &#(Digit)+; | &#x(Digit|a...f|A...F)+;
Letter -> a...z | A...Z
Digit -> 0...9
I «Нет эксперта, но я знаю, что для этого нужно использовать регулярные выражения. Так что мой Tokenizer теперь выглядит следующим образом:
public Tokenizer(String str) {
this.tokenContents = new ArrayList<TokenContent>();
this.str = str;
// Name = Initial Other*
String initial = "[a-zA-Z] | _ | :";
String other = initial + " | [0-9] | - | \\.";
String name = initial + "(" + other + ")*";
tokenContents.add(new TokenContent(Pattern.compile(name), TokenType.NAME));
// String = " " (Char | ')* " | ' (Char | ")* '
String ordinary = "(?!(< | > | \" | ' | &))";
String special = "< | > | " | ' | &";
String reference = "&#[0-9]+; | &#x([0-9] | [a-fA-F])+;";
String character = ordinary + " | " + special + " | " + reference;
String string = "\"(" + character + " | " + "')* \" | ' (\"" + character + " | " + "\")* '";
tokenContents.add(new TokenContent(Pattern.compile(string), TokenType.STRING));
// Data = Char+
String data = character + "+";
tokenContents.add(new TokenContent(Pattern.compile(data), TokenType.DATA));
// The symbol <
tokenContents.add(new TokenContent(Pattern.compile("<"), TokenType.LEFT_TAG));
// The symbol >
tokenContents.add(new TokenContent(Pattern.compile(">"), TokenType.RIGHT_TAG));
// The symbol </
tokenContents.add(new TokenContent(Pattern.compile("</"), TokenType.LEFT_TAG_SLASH));
// The symbol />
tokenContents.add(new TokenContent(Pattern.compile("/>"), TokenType.RIGHT_TAG_SLASH));
// The symbol =
tokenContents.add(new TokenContent(Pattern.compile("="), TokenType.EQUALS));
}
Для простоты, вы можете видеть, я мое регулярное модульное выражение в соответствии с приведенной выше спецификацией. Однако, после нескольких тестовых примеров запуска lexer на примерном входном файле, я получаю ошибки синтаксического анализа. Я считаю, что это могут быть мои регулярные выражения, поэтому Мне бы хотелось, чтобы некоторые предложения о том, как я могу правильно перевести приведенную выше спецификацию в код и исправить мой токенизатор.
Мои жетоны Name
, String
, Data
, <
, >
, </
, />
и =
. Все они указаны в классе enum
, который здесь не отображается. Пример входного файла:
<recipe name="bread" prep_time="5 mins" cook_time="3 hours">
<title>Basic bread</title>
<ingredient amount="3" unit="cups">Flour</ingredient>
<ingredient amount="0.25" unit="ounce">Yeast</ingredient>
<ingredient amount="1.5" unit="cups" state="warm">Water</ingredient>
<ingredient amount="1" unit="teaspoon">Salt</ingredient>
<instructions>
<step>Mix all ingredients together.</step>
<step>Knead thoroughly.</step>
<step>Cover with a cloth, and leave for one hour in warm room.</step>
<step>Knead again.</step>
<step>Place in a bread baking tin.</step>
<step>Cover with a cloth, and leave for one hour in warm room.</step>
<step>Bake in the oven at 350° F for 30 minutes.</step>
</instructions>
</recipe>
Я никогда раньше не работал с регулярными выражениями, поэтому это первый для меня. Я был бы очень признателен за любые материалы, которые могли бы помочь.
Пожалуйста, разместите несколько тестовых примеров, которые вы пытаетесь проанализировать. – 11thdimension
Добавлен пример входного файла. Благодаря! –
Вы не можете использовать простой синтаксический анализ XML? – 11thdimension