2012-07-02 3 views
0

Мне нужно «{» будет одиночным на линии. Поэтому я должен использовать токен, который его распознает. Это правые примеры:Токен в JavaCC: убедитесь, что символ один на линии

program 
{ 

или

program 



{ 

И это некорректны примеры:

program { 

или

program 
{ sentence; 

Тогда у меня есть знак, как это:

TOKEN: { < openKey: "{" > {System.out.print(image +"\n");}} 
SKIP: { < (" " | "\r" | "\t" | "\n")+ > } 

Но я не могу думать, как сделать символ «{» точно между одним или несколькими «\ n». И после того, как узнал его, я должен написать именно:

program 
{ 

Если я пытаюсь:

TOKEN: { < openKey: (" " | "\r" | "\t" | "\n")+ "{" (" " | "\r" | "\t" | "\n")+ > {System.out.print(image +"\n");}} 

Это идет, но он пишет так много «\ п», как там было на входе.

ответ

0

Я сделал это по-другому:

TOKEN: { < openKey: "\n" (" " | "\t")* "{" (" " | "\t")* ("\r" | "\n") >{System.out.print("{\r\n");}} 
SKIP: { " " | "\r" | "\t" | "\n" } 

Были некоторые проблемы с возвратом каретки, но этот способ хорошо работает

.
0

Основная проблема заключается в том, что вы печатаете ввод без какой-либо интерпретации. Другими словами, что происходит, это то, что вышло, как вы обнаружили.

Чтобы было легче читать --- и чтобы не было в некотором отношении неправильным использованием лексического анализатора, заставляя его выполнять всю задачу --- я рекомендую переместить инструкцию печати в синтаксический анализатор (например, в функции 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 или более новых строк.

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

В любом случае, основная предпосылка этого ответа --- и я считаю, что это действительно что-то важное для возрастов, подходящее для использования во всех сферах жизни, а не только для кодирования --- «Если вы не измените то, что вы возьмите, прежде чем вывести его, это будет именно то, что вы приняли!"