忽略 Island 语法中的特殊字符
Ignoring Special Characters in an Island Grammar
我有以下岛屿语法可以正常工作(我认为符合预期):
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 词法分析器标记匹配所有文本。当然除了 '#' 和 '~' 之外,所以解析器知道什么时候有标题和列表。
我的问题是在文本中应该允许使用字符“#”和“~”。只有标题需要单个“#”,并且此解析器规则在 body 中无效(文档开头只有一个标题)。
有没有办法让'#'和'~'在文本中不转义?我的第一个想法是在文本中禁止使用“##”:
TEXT : ~('##'|'~')+;
但是那里不允许有多个字符。 :(
也许有人可以给我提示。但我认为这根本无法解决。我的意思是用 ANTLR4 无法解决。也许还有另一种技术。
您可以尝试在解析器中做更多的工作,而在词法分析器中做更少的工作。允许 #
和 ~
在 text
内而不是在 TEXT
内,类似于 到:
text
: TEXT
: OPEN1
: TEXT text
: OPEN1 text
;
相应地调整标题等规则。
这样,词法分析器不必决定#
(或~
)是什么意思,相对困难的是什么,因为词法分析器并不真正知道上下文,但它只决定它看到了井号。相反,解析器决定它的含义,并且它知道它出现的上下文。
我有以下岛屿语法可以正常工作(我认为符合预期):
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 词法分析器标记匹配所有文本。当然除了 '#' 和 '~' 之外,所以解析器知道什么时候有标题和列表。
我的问题是在文本中应该允许使用字符“#”和“~”。只有标题需要单个“#”,并且此解析器规则在 body 中无效(文档开头只有一个标题)。
有没有办法让'#'和'~'在文本中不转义?我的第一个想法是在文本中禁止使用“##”:
TEXT : ~('##'|'~')+;
但是那里不允许有多个字符。 :(
也许有人可以给我提示。但我认为这根本无法解决。我的意思是用 ANTLR4 无法解决。也许还有另一种技术。
您可以尝试在解析器中做更多的工作,而在词法分析器中做更少的工作。允许 #
和 ~
在 text
内而不是在 TEXT
内,类似于 到:
text
: TEXT
: OPEN1
: TEXT text
: OPEN1 text
;
相应地调整标题等规则。
这样,词法分析器不必决定#
(或~
)是什么意思,相对困难的是什么,因为词法分析器并不真正知道上下文,但它只决定它看到了井号。相反,解析器决定它的含义,并且它知道它出现的上下文。