2016-06-04 2 views
-1

Я следующую грамматику остров, который работает прекрасно (и я думаю, как и следовало ожидать):Игнорирование специальных символов в Островом Грамматика

lexer grammar FastTestLexer; 

// Default mode rules (the SEA) 
OPEN1 : '#' -> mode(ISLAND) ; // switch to ISLAND mode 
OPEN2 : '##' -> mode(ISLAND); 
OPEN3 : '###' -> mode(ISLAND); 
OPEN4 : '####' -> mode(ISLAND); 
LISTING_OPEN : '~~~~~' -> mode(LISTING); 
NL : [\r\n]+; 
TEXT : ~('#'|'~')+; // ~('#'|'~')+ ; // clump all text together 

mode ISLAND; 
CLOSE1 : '#' -> mode(DEFAULT_MODE) ; // back to SEA mode 
CLOSE2 : '##' -> mode(DEFAULT_MODE) ; // back to SEA mode 
CLOSE3 : '###' -> mode(DEFAULT_MODE) ; // back to SEA mode 
CLOSE4 : '####' -> mode(DEFAULT_MODE) ; // back to SEA mode 
INLINE : ~'#'+ ; // clump all text together 

mode LISTING; 
LISTING_CLOSE : '~~~~~' -> mode(DEFAULT_MODE); 
INLINE_LISTING : ~'~'+; //~('~'|'#')+; 

И грамматика парсер:

parser grammar FastTextParser; 

options { tokenVocab=FastTestLexer; } // use tokens from ModeTagsLexer.g4 

dnpMD 
    : subheadline NL headline NL lead (subheading | listing | text | NL)* 
    ; 

headline 
    : OPEN1 INLINE CLOSE1 
    ; 

subheadline 
    : OPEN2 INLINE CLOSE2 
    ; 

lead 
    : OPEN3 INLINE CLOSE3 
    ; 

subheading 
    : OPEN4 INLINE CLOSE4 
    ; 

listing 
    : LISTING_OPEN INLINE_LISTING LISTING_CLOSE 
    ; 

text 
    : TEXT 
    ; 

Введите текст как эти рабочие работают нормально:

## Heading2 ## 

# Heading1 # 

### Heading3 ### 

fffff 

#### Heading4 #### 

I'm a line. 

~~~~~ 
ffffff 
~~~~~ 

I'm a line, too. 

#### Heading4a #### 

Тонер лексера TEXT соответствует всему тексту. Конечно, кроме «#» и «~», поэтому парсер знает, когда появятся заголовки и списки.

Моя проблема заключается в том, что внутри текста должны быть разрешены символы «#» и «~». Единственный «#» нужен только для заголовка, и это правило парсера неактивно внутри тела (всего один заголовок в начале документа).

Есть ли способ разрешить '#' и '~' в тексте без экранирования? Моя первая мысль заключалась в том, чтобы запретить «##» в тексте:

TEXT : ~('##'|'~')+; 

Но несколько символов там не допускаются. :(

Может быть кто-то может дать мне подсказку. Но я думаю, что это не разрешимы вообще. Не разрешимы ANTLR4 я имею в виду. Может быть, есть другая технология.

ответ

1

Вы могли бы попытаться сделать больше работы в парсер и меньше в лексере Разрешить # и ~ внутри text и не внутри TEXT, что-то похожи на:..

text 
    : TEXT 
    : OPEN1 
    : TEXT text 
    : OPEN1 text 
    ; 

Настройте правила для заголовков и т.д. соответственно

Таким образом, не лексер должен решить, что такое # (или ~) означает, что может быть относительно сложно, потому что лексер действительно не знает контекста, но только решает, что он видел хэш-знак. Вместо этого синтаксический анализатор решает смысл его, и он знает контекст, в котором он появляется.

+0

Hm okay. Не совсем уверен, правильно ли понимаю ваше предложение, но я попробую. – FDeitelhoff

+0

Спасибо. Это помогло мне в сочетании с другим ответом на другой вопрос. ;) – FDeitelhoff

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