2016-03-05 5 views
2

Я пишу плагин пользовательского языка для IntelliJ.IntelliJ: Grammar-Kit/BNF: как оправиться от ошибок?

Вот упрощенный пример языка. Обратите внимание, что структура является рекурсивным:

enter image description here

Я успешно реализованы файлы FLEX и BNF, но я не уверен, как добавить исправление ошибок. Я читал около RecoverWhile и pin в HOWTO Grammar-Kit, но я не уверен, как применить их к моему сценарию.

Я называю коричневые предметы выше («aaa», «ccc» и т. Д.) «штук».

Я называю желтые («bbb», «ddd», ...) «объектов недвижимости».

Каждого элемент имеет имя пункта (например, «ааа»), один свойства (например, «В»), и может содержать другие элементы (например, «ааа» содержит «КТС», «ээээ», и "gg").

На данный момент плагин не ведет себя хорошо, когда элемент имеет неправильный характер. Например:

enter image description here

В этом примере я хотел бы парсер «понять», что «ссс» это имя в пункта с отсутствующим свойством (например, путем обнаружения новой строки перед закрытием скобка).

Я не хочу сломанный «КТС» пункт влиять на парсинг «EEEE» (но я хочу, чтобы дерево PSI, чтобы элементы «ссс», которые присутствуют в тексте, в этом case - его название).

Вот FLEX и BNF, которые я использую:

FLEX:

CRLF= \n|\r|\r\n 
WS=[\ \t\f] 
WORD=[a-zA-Z0-9_#\-]+ 

%state EOF 

%% 
<YYINITIAL> {WORD} { yybegin(YYINITIAL); return MyLangTypes.TYPE_FLEX_WORD; } 
<YYINITIAL> \[  { yybegin(YYINITIAL); return MyLangTypes.TYPE_FLEX_OPEN_SQUARE_BRACKET; } 
<YYINITIAL> \]  { yybegin(YYINITIAL); return MyLangTypes.TYPE_FLEX_CLOSE_SQUARE_BRACKET; } 
<YYINITIAL> \{  { yybegin(YYINITIAL); return MyLangTypes.TYPE_FLEX_OPEN_CURLY_BRACKET; } 
<YYINITIAL> \}  { yybegin(YYINITIAL); return MyLangTypes.TYPE_FLEX_CLOSE_CURLY_BRACKET; } 
({CRLF}|{WS})+  { return TokenType.WHITE_SPACE; } 
{WS}+     { return TokenType.WHITE_SPACE; } 
.      { return TokenType.BAD_CHARACTER; } 

BNF:

myLangFile ::= (item|COMMENT|CRLF) 
item ::= 
    itemName 
    (TYPE_FLEX_OPEN_SQUARE_BRACKET itemProperty? TYPE_FLEX_CLOSE_SQUARE_BRACKET?)? 
    itemBody? 
itemName ::= TYPE_FLEX_WORD 
itemProperty ::= TYPE_FLEX_WORD 
itemBody ::= TYPE_FLEX_OPEN_CURLY_BRACKET item* TYPE_FLEX_CLOSE_CURLY_BRACKET 
+0

Вы нашли ответ? –

+0

@IrinaRapoport ... Я смог обойти его. Я не помню всех подробностей, так как это было какое-то время, но я отправил ответ на основе окончательного кода, который у меня есть сейчас ... надеюсь, что это поможет! – obe

ответ

0

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

myLangFile ::= (item|COMMENT|CRLF) 
item ::= 
    itemName 
    itemProperties 
    itemBody? 
itemName ::= TYPE_FLEX_WORD 
itemProperties ::= TYPE_FLEX_OPEN_SQUARE_BRACKET [!TYPE_FLEX_CLOSE_SQUARE_BRACKET itemProperty ((TYPE_FLEX_SEMICOLON itemProperty)|itemProperty)*] TYPE_FLEX_CLOSE_SQUARE_BRACKET { 
    pin(".*") = 1 
} 
itemProperty ::= TYPE_FLEX_WORD TYPE_FLEX_EQUALS? itemPropertyValue? (TYPE_FLEX_EQUALS prv_swallowNextPropertyToPreventSyntaxErrors)? 
private prv_swallowNextPropertyToPreventSyntaxErrors ::= TYPE_FLEX_WORD 
itemPropertyValue ::= TYPE_FLEX_WORD 
itemBody ::= TYPE_FLEX_OPEN_CURLY_BRACKET item* TYPE_FLEX_CLOSE_CURLY_BRACKET 

Это не perfe кт; например, он позволяет разделить свойства элемента с пространством (а не только с точкой с запятой), но он, похоже, решает более важную проблему.

Это также может быть интересно: https://github.com/JetBrains/Grammar-Kit/blob/master/resources/messages/attributeDescriptions/recoverWhile.html

 Смежные вопросы

  • Нет связанных вопросов^_^