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



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

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 : [rn]+;
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 : ~('##'|'~')+;

但是那里不允许使用多个字符。 :(

也许有人可以给我一个提示。但我认为这根本无法解决。我的意思是 ANTLR4 无法解决。也许还有另一种技术。

您可以尝试在解析器中做更多的工作,而在词法分析器中做更少的工作。允许#~text内而不是在TEXT内,类似于:

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

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

这样,词法分析器不必决定#(或~)的含义,什么是相对困难的,因为词法分析器并不真正知道上下文,但它只决定它已经看到了哈希符号。相反,解析器决定它的含义,并且知道它出现的上下文。

相关内容

  • 没有找到相关文章

最新更新