023abc7defghij
字符0,1 =以下块的大小
第一个字符=以下字符串String的长度
以下字符=具有指定长度的字符串
所以在上面的例子中,这意味着:
02 - >以下2个块
3 - > 3个字符串将跟随
abc - >三个字符串
7 - >将跟随7个字符串
defghij - >七个字符串
我可以写一个语法,描述这种形式的字符串吗? 我需要解释'length'信息,然后用指定的长度构建标记,用长度信息和字符串填充我的对象。
我希望我可以形容这种可理解性。我无法找到信息,描述或解决我的问题。
答案 0 :(得分:2)
我假设您的实际问题有点复杂,因为如果"023abc7defghij"
是您的实际输入,我不会使用像ANTLR这样的解析器生成器,而只是坚持一些简单的字符串操作。 / p>
那就是说,这是一个可能的解决方案:
由于预先不知道chunks
,因此您无法创建除单个Digit
和Other
令牌之外的任何令牌,这些令牌可以是除数字之外的任何字符。请注意,您并不真正需要header
信息:您只需解析"3"
然后获取接下来的3个字符,然后解析"7"
并获得接下来的7个字符,...一直到文件的末尾。
这种语言的语法可能如下所示:
grammar T;
parse
: file EOF
;
file
: header chunk*
;
header
: Digit Digit
;
chunk
: Digit any*
;
any
: Digit
| Other
;
Digit
: '0'..'9'
;
Other
: .
;
但是现在chunk
规则含糊不清:它现在不会停止消费字符。这可以使用gated semantic predicate来完成,这会导致*
any*
在满足特定条件时停止消费(当计数器int n
倒计时时,在这种情况下)。
上面的语法包括这个谓词和一些println
- 语句看起来像这样:
grammar T;
parse
: file EOF
;
file
: header {System.out.println("header=" + $header.text);}
(chunk {System.out.println("chunk=" + $chunk.text);})*
;
header
: Digit Digit
;
chunk
: Digit {int n = Integer.valueOf($Digit.text);} ({n > 0}?=> any {n--;})*
;
any
: Digit
| Other
;
Digit
: '0'..'9'
;
Other
: .
;
可以在课堂上进行测试:
import org.antlr.runtime.*;
public class Main {
public static void main(String[] args) throws Exception {
String source = "023abc7defghij";
TLexer lexer = new TLexer(new ANTLRStringStream(source));
TParser parser = new TParser(new CommonTokenStream(lexer));
parser.parse();
}
}
如果您现在生成词法分析器和解析器,请编译所有.java
文件并运行Main
类:
java -cp antlr-3.3.jar org.antlr.Tool T.g
javac -cp antlr-3.3.jar *.java
java -cp .:antlr-3.3.jar Main
您会看到以下内容正在打印到您的控制台:
header=02
chunk=3abc
chunk=7defghij