Основная проблема заключается в том, что вы печатаете ввод без какой-либо интерпретации. Другими словами, что происходит, это то, что вышло, как вы обнаружили.
Чтобы было легче читать --- и чтобы не было в некотором отношении неправильным использованием лексического анализатора, заставляя его выполнять всю задачу --- я рекомендую переместить инструкцию печати в синтаксический анализатор (например, в функции Start()). (На самом деле я вообще полностью переношу весь свой вывод из анализатора, если только я не делаю что-то очень малое, что я никогда не буду повторно использовать, но это для другого вопроса.)
Далее, чтобы решить актуальную проблему , вы делаете некоторую интерпретацию, чтобы получить от пучка новых строк до одного. Самый простой способ сделать это - basic replaceAll. Вот моя функция Start(), где openKey определяется так же, как вы это сделали, и WORD - это просто конкатенация букв.
void Start() :
{
Token t;
}
{
(
t = <WORD>
{System.out.print((t.image).replaceAll("(\n)+","\n"));}
)*
(
t = <openKey>
{System.out.print((t.image).replaceAll("(\n)+","\n"));}
(
t = <WORD>
{System.out.print((t.image).replaceAll("(\n)+","\n"));}
)*
)*
<EOF>
}
Поэтому в основном, это занимает ноль или более слов, за которым следует блок, который состоит из 1 или более новых строк с последующим левой фигурной скобки, затем 1 или более символами новой строки, а затем на ноль или больше слов и выводит слова, фигурные скобки и только 1 новую строку для набора из 1 или более новых строк.
Если вы можете запустить файл с фигурной скобкой, вместо того чтобы требовать слово, то он выводит и пустую строку, фигурные скобки и новую строку. Я не знаю, хочет ли это то, что вы хотите, имея возможность начать вывод с пустой строкой, поэтому вам нужно будет сыграть с кодом вывода, чтобы получить точный формат, за который вы собираетесь, плюс, поскольку вы можете видеть вас У меня есть очень хороший повторяющийся код, который можно извлечь из функции, поэтому я оставляю это для упражнения для читателя.
В любом случае, основная предпосылка этого ответа --- и я считаю, что это действительно что-то важное для возрастов, подходящее для использования во всех сферах жизни, а не только для кодирования --- «Если вы не измените то, что вы возьмите, прежде чем вывести его, это будет именно то, что вы приняли!"