Я пишу JavaCC синтаксический анализатор/лексера который предназначен распознавать все входные строки, принадлежащие к одному из следующих языков L0 или L1:Как справиться с «Расширением внутри» (...) * «может быть сопоставлено пустая строка»?
L0
Строка из L0 состоит из нескольких блоков, разделенных пробелами , Должен присутствовать хотя бы один блок (т. Е. Не допускается вход, состоящий только из некоторого количества пробелов).
- Блок представляет собой последовательность строчных букв без буквы (a-z).
- Перед первым блоком или после последнего пробела не допускается пробел.
- Число пробелов между блоками должно быть нечетным.
L1
Строка из L1 состоит из нескольких блоков, разделенных пробелами. Должен присутствовать хотя бы один блок.
- Существует два вида блоков. Блок первого типа должен быть четной последовательностью заглавных букв
(A-Z)
. Блок второго типа должен иметь форму<2U>. . .</2U>
, где. . .
стоит для любой строки из L0. - Перед первым блоком или после последнего пробела не допускается пробел.
- Число пробелов между блоками должно быть нечетным.
Это мой код до сих пор:
PARSER_BEGIN(Assignment)
/** A parser which determines if user's input belongs to L0 or L1. */
public class Assignment {
public static void main(String[] args) {
String returnString = null;
boolean toPrintEmptyInput = false;
try {
Assignment parser = new Assignment(System.in);
if(parser.Input()) {
System.out.println("YES"); // If the user's input belongs to L0, print YES.
} else {
System.out.println("NO");
}
} catch (ParseException e) {
System.out.println("NO"); // If the user's input does not belong to L0, print NO.
}
}
}
PARSER_END(Assignment)
//** A token which matches any lowercase letter from the English alphabet. */
TOKEN :
{
< IDLOWER: (["a"-"z"]) >
}
//* A token which matches any uppercase letter from the English alphabet. */
TOKEN:
{
< IDUPPER: (["A"-"Z"]) >
}
//* A token which matches a single white space. */
TOKEN :
{
<WHITESPACE: " ">
}
/** This production is the basis for the construction of strings which belong to language L0. */
boolean Input() :
{}
{
<IDLOWER>(<IDLOWER><IDLOWER>)* ((<WHITESPACE>(<WHITESPACE><WHITESPACE>)*)<IDLOWER>(<IDLOWER><IDLOWER>)*)* ("\n"|"\r") <EOF>
{
return true;
}
|
{
return false;
}
}
/** This production is the basis for the construction of strings which belong to language L1. */
void Input2() :
{}
{
Input() ((<WHITESPACE> Input())* (<WHITESPACE> (<IDUPPER><IDUPPER>)+)*)* ("\n"|"\r") <EOF>
|
(<IDUPPER><IDUPPER>)+ ((<WHITESPACE> (<IDUPPER><IDUPPER>)+)* (<WHITESPACE> Input())*)* ("\n"|"\r") <EOF>
}
Выпуск: Вопрос, который я имею, что, когда я бегу javacc
на Assignment.jj
следующее печатается на терминале: Expansion within "(. . .)*" can be matched by empty string.
Я посмотрел на следующие ссылки для того, чтобы попытаться лучше понять эту ошибку:
Вторая ссылка рекомендовала модифицировать . . .
в пределах расширения, чтобы его нельзя было сопоставить с нулем. Тем не менее, я изо всех сил стараюсь сделать это, все еще имея производство, которое принимает строки в L1.
Я бы оценил советы или исправления!
'B' в' (A * B *) * ', но не в' (A + B *) * '. Аналогично «BB» и т. Д. Я бы предложил «B * (A B *) *». –
@theodore: совершенно верно. Я изменил его на строгий эквивалент. Если оператор '|' не был возможен, можно было бы ввести другой нетерминал. – rici
Да '(A | B) *' лучше. –