gpt4 book ai didi

parsing - ANTLR 规则消耗固定数量的字符

转载 作者:行者123 更新时间:2023-12-04 15:27:21 24 4
gpt4 key购买 nike

我正在尝试为 PHP serialize() 格式编写 ANTLR 语法,除了字符串外,一切似乎都正常。问题是序列化字符串的格式是:

s:6:"length";

在正则表达式方面,像 s:(\d+):".{\1}"; 这样的规则如果在“匹配数”计数中只允许反向引用(但它们不是),则将描述这种格式。

但是我找不到一种方法来为词法分析器或解析器语法表达这一点:整个想法是使读取的字符数取决于描述要读取的字符数的反向引用,如 Fortran Hollerith 常量(即 6HLength ),而不是字符串分隔符。

这个例子来自 ANTLR grammar for Fortran似乎指明了方向,但我不明白如何。请注意,我的目标语言是 Python,而大部分文档和示例都是针对 Java 的:
// numeral literal
ICON {int counter=0;} :
/* other alternatives */
// hollerith
'h' ({counter>0}? NOTNL {counter--;})* {counter==0}?
{
$setType(HOLLERITH);
String str = $getText;
str = str.replaceFirst("([0-9])+h", "");
$setText(str);
}
/* more alternatives */
;

最佳答案

由于输入像 s:3:"a"b";有效,您不能定义 String词法分析器中的标记,除非第一个和最后一个双引号是 总是 字符串的开头和结尾。但我想情况并非如此。

所以,你需要一个像这样的词法分析器规则:

SString
: 's:' Int ':"' ( . )* '";'
;

换句话说:匹配 s: ,然后是 integer值后跟 :"然后一个或多个可以是任何字符的字符,以 "; 结尾.但是您需要告诉词法分析器在值 Int 时停止使用。未达到。您可以通过在语法中混合一些纯代码来做到这一点。您可以通过将其包装在 { 中来嵌入纯代码和 } .所以首先将值转换为 token Int保存到一个名为 chars 的整数变量中:
SString
: 's:' Int {chars = int($Int.text)} ':"' ( . )* '";'
;

现在在 ( . )* 中嵌入一些代码循环以尽快停止消耗 chars倒计时为零:
SString
: 's:' Int {chars = int($Int.text)} ':"' ( {if chars == 0: break} . {chars = chars-1} )* '";'
;

就是这样。

一个小演示语法:
grammar Test;

options {
language=Python;
}

parse
: (SString {print 'parsed: [\%s]' \% $SString.text})+ EOF
;

SString
: 's:' Int {chars = int($Int.text)} ':"' ( {if chars == 0: break} . {chars = chars-1} )* '";'
;

Int
: '0'..'9'+
;

(请注意,您需要在语法中转义 %!)

和一个测试脚本:
import antlr3
from TestLexer import TestLexer
from TestParser import TestParser

input = 's:6:"length";s:1:""";s:0:"";s:3:"end";'
char_stream = antlr3.ANTLRStringStream(input)
lexer = TestLexer(char_stream)
tokens = antlr3.CommonTokenStream(lexer)
parser = TestParser(tokens)
parser.parse()

产生以下输出:
parsed: [s:6:"length";]
parsed: [s:1:""";]
parsed: [s:0:"";]
parsed: [s:3:"end";]

关于parsing - ANTLR 规则消耗固定数量的字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4010549/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com