【发布时间】:2015-09-27 23:25:24
【问题描述】:
我正在研究一种基本上是孤岛语法的语法。
假设“岛”是大括号之间的一切,“海”是一切不是的。像这样:
{(岛屿内容)}
那么这个简单的语法就起作用了:
IslandStart
:
'{' -> pushMode(Island)
;
Fluff
:
~[\{\}]+
;
....
但是我很难想出一个类似的解决方案来解决我想要为我的“岛”块打开复杂(多字符)的情况,就像这样:
{#(岛屿内容)}
在这种情况下,我不知道如何为“Fluff”(除了我的开场序列之外的所有内容)制定规则。
IslandStart
:
'{#' -> pushMode(Island)
;
Fluff
:
~[\{\}]+ /* Should now include opening braces as well
if they are not immaediately followed by # sign */
;
如何让它发挥作用?
编辑:格罗森伯格想出了一个解决方案,但我得到了很多令牌(每个字符一个)。这是演示此行为的示例:
我的词法分析器语法:
lexer grammar Demolex;
IslandStart
:
'{$' -> pushMode(Island)
;
Fluff
:
'{' ~'$' .* // any 2+ char seq that starts with '{', but not '{#'
| '{' '$$' .* // starts with hypothetical not IslandStart marker
| '{' // just the 1 char
| .*? ~'{' // minimum sequence that ends before an '{'
;
mode Island;
IslandEnd
:
'}' -> popMode
;
最简单的解析器语法:
grammar Demo;
options { tokenVocab = Demolex; }
template
:
Fluff+
;
当我在 Eclipse 的 antlr4 插件中调试它时,这会从输入“somanytokens”中生成一个包含大量令牌的树:
这不太可能是插件问题。我可以很容易地想出一个令牌定义,它会在树中产生一个大的胖令牌。
实际上,即使是最简单的语法形式也会给出这样的结果:
grammar Demo2;
template4
:
Fluff+
;
Fluff
:
.*? ~'{' // minimum sequence that ends before an '{'
;
【问题讨论】: