Nic*_* B. 5 c# regex parsing text-parsing antlr4
我想解析纯文本注释并在其中查找某些标签。我要寻找的标签类型如下:
<name#1234>
Run Code Online (Sandbox Code Playgroud)
其中“名称”是[az]字符串(来自固定列表),“ 1234”表示[0-9] +数字。这些标签可以出现在字符串中零次或多次,并被任意其他文本包围。例如,以下字符串均有效:
"Hello <foo#56> world!"
"<bar#1>!"
"1 < 2"
"+<baz#99>+<squid#0> and also<baz#99>.\n\nBy the way, maybe <foo#9876>"
Run Code Online (Sandbox Code Playgroud)
以下字符串均无效:
"1 < 2"
"<foo>"
"<bar#>"
"Hello <notinfixedlist#1234>"
Run Code Online (Sandbox Code Playgroud)
最后一个无效,因为“ notinfixedlist”不是受支持的命名标识符。
我可以使用简单的正则表达式轻松地对此进行解析(例如,为简单起见,我省略了命名组):
<[a-z]+#\d+>
Run Code Online (Sandbox Code Playgroud)
或直接指定一个固定列表:
<(foo|bar|baz|squid)#\d+>
Run Code Online (Sandbox Code Playgroud)
但出于某些原因,我想使用antlr:
如何使用antlr4实施这样的语法?我看到的大多数示例都是针对遵循完整文本严格规则的语言的,而我只希望语法适用于任意文本内的匹配模式。
我想出了这个,我认为是正确的:
grammar Tags;
parse
: ( tag | text )*
;
tag
: '<' fixedlist '#' ID '>'
;
fixedlist
: 'foo'
| 'bar'
| 'baz'
| 'squid';
text
: ~('<' | '>')+
;
ID
: [0-9]+
;
Run Code Online (Sandbox Code Playgroud)
它是否正确?
一般来说,所识别的问题通常被描述为孤岛语法问题——其中单个文档的各个部分由两个或多个不同的、通常相互模糊的规范来描述。
ANTLR 4 通过使用modes 直接支持岛语法。请注意,模式仅在拆分词法分析器/解析器语法中可用。
解析器
parser grammar TagsParser ;
options {
tokenVocab = TagsLexer ;
}
parse : ( tag | text )* EOF ;
tag : LANGLE fixedlist GRIDLET ID RANGLE ;
text : . ;
fixedlist
: FOO
| BAR
| BAZ
| SQUID
;
Run Code Online (Sandbox Code Playgroud)
词法分析器
lexer grammar TagsLexer ;
LANGLE : '<' -> pushMode(tag) ;
TEXT : . ;
mode tag ;
RANGLE : '>' -> popMode ;
FOO : 'foo' ;
BAR : 'bar' ;
BAZ : 'baz' ;
SQUID : 'squid' ;
GRIDLET : '#' ;
ID : [0-9]+ ;
NONTAG : . -> popMode ;
Run Code Online (Sandbox Code Playgroud)
text解析器中的规则将匹配其上方的解析器规则之前未使用的所有标记。这将包括所有TEXT标记以及恰好与标记模式规则匹配但不是标记的有效部分的任何文本。
| 归档时间: |
|
| 查看次数: |
131 次 |
| 最近记录: |