Проблемы JISON с командой синтаксического анализа

Привет, я новичок в JISON и застрял в следующем коде:
Для синтаксического анализа команды:

 project -a -n <projectname>  

Мой код выглядит следующим образом:

"project"   {return 'PROJECTCOMMAND';}
"-n"        {return 'NAMEOPTION';}
("--add"|"-a")  {return 'ADDOPTION';}  
[-a-zA-Z0-9@\.]+ {return 'TEXT';}

line :   
   PROJECTCOMMAND ADDOPTION NAMEOPTION TEXT 
            {
                //Prject command with project name as argument
                var res = new Object();
                res.value = "addProject name";
                res.name = $4;
                return res;  
            }  

Это отлично работает, если команда выглядит следующим образом:

project -a -n samplePro  

Но выдает ошибку, если команда:

project -a -n project  

Ошибка: ожидание TEXT и получение PROJECTCOMMAND.
То же самое происходит, если имя проекта в команде — project1, project2, myproject и т. д.. Можно ли это как-то исправить?
Заранее спасибо


person Abhishek    schedule 20.11.2014    source источник


Ответы (1)


Один из способов решить эту проблему — использовать состояние. Формальное название того, что я называю здесь «состоянием», — «начальное состояние», но я считаю, что «состояние» для меня более понятный термин, чем «начальное состояние».

  1. Я объявил новое состояние лексера с помощью %x TEXT. Существует состояние INITIAL, которое существует неявно. Это состояние, в котором запускается лексер. Любой шаблон, который не получает указанное состояние, существует только в состоянии INITIAL.

  2. Я поставил <TEXT> перед шаблоном, который приводит к токену TEXT, чтобы этот токен генерировался только, когда мы находимся в состоянии TEXT.

  3. Я установил шаблон для пробелов, чтобы они применялись к состояниям INITIAL и TEXT.

  4. Я сделал так, что -n заставляет лексер входить в состояние TEXT, а когда встречается токен TEXT, состояние выталкивается.

При этом, когда Джисон встречает -n в project -a -n project, он переходит в состояние TEXT, где ожидаются только пробелы, которые игнорируются, или жетоны TEXT. Затем Jison обрабатывает пустое пространство, которое игнорирует. Затем он обрабатывает текст, который следует за токеном TEXT, и извлекает состояние.

Полный код:

%lex

%x TEXT

%%
"project"   {return 'PROJECTCOMMAND';}
"-n"        {this.begin('TEXT'); return 'NAMEOPTION';}
("--add"|"-a")  {return 'ADDOPTION';}  
<TEXT>[-a-zA-Z0-9@\.]+ {this.popState(); return 'TEXT';}
<INITIAL,TEXT>\s+         // Ignore white space...

/lex

%%

line :   
   PROJECTCOMMAND ADDOPTION NAMEOPTION TEXT 
            {
                //Prject command with project name as argument
                var res = new Object();
                res.value = "addProject name";
                res.name = $4;
                return res;  
            }  ;
person Louis    schedule 20.11.2014
comment
Спасибо за ответ. Не могли бы вы поделиться со мной любыми руководствами, где я могу узнать об этих состояниях, begin('TEXT'), popState() - person Abhishek; 20.11.2014