忽略岛屿语法中的特殊字符

时间:2016-06-04 19:43:26

标签: parsing antlr4

我有以下岛屿语法工作正常(我认为如预期的那样):

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 个答案:

答案 0 :(得分:1)

您可以尝试在解析器中执行更多工作,而在词法分析器中执行更少操作。允许在#~text而不在TEXT内,类似

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

相应地调整标题等的规则。

那样的话,不是词法分析者必须决定#(或~)的意思,什么可能比较难,因为词法分析者并不真正知道上下文,但它只决定它已经看到一个哈希标志。相反,解析器决定它的含义,并且它知道它出现的上下文。