Properties ANTLR解析Java属性
我正在尝试学习ANTLR并为Java属性编写语法。我在这里遇到了一个问题,希望能得到一些帮助 在Java属性中,它有一点奇怪的转义处理。比如说,Properties ANTLR解析Java属性,properties,antlr,grammar,Properties,Antlr,Grammar,我正在尝试学习ANTLR并为Java属性编写语法。我在这里遇到了一个问题,希望能得到一些帮助 在Java属性中,它有一点奇怪的转义处理。比如说, key1=1=Key1 key\=2== 在Java运行时中生成键值对,如下所示 KEY VALUE === ===== key1 1=Key1 key=2 = 到目前为止,这是我能模仿的最好的。。通过将“=”和值折叠成一个标记 grammar Prop; file : (pair | LINE_COMMENT)* ; p
key1=1=Key1
key\=2==
在Java运行时中生成键值对,如下所示
KEY VALUE
=== =====
key1 1=Key1
key=2 =
到目前为止,这是我能模仿的最好的。。通过将“=”和值折叠成一个标记
grammar Prop;
file : (pair | LINE_COMMENT)* ;
pair : ID VALUE ;
ID : (~('='|'\r'|'\n') | '\\=')* ;
VALUE : '=' (~('\r'|'\n'))*;
CARRIAGE_RETURN
: ('\r'|'\n') + {$channel=HIDDEN;}
;
LINE_COMMENT
: '#' ~('\r'|'\n')* ('\r'|'\n'|EOF)
;
如果我能实施一个更好的方案,有什么好的建议吗?
非常感谢没那么容易。你不能在词法层次上处理很多事情,因为很多事情都依赖于特定的上下文。因此,在词法层次上,您只能匹配单个字符并在解析器规则中构造键和值。此外,作为可能的键值分隔符的
=
和:
以及这些字符可以作为值的开头这一事实,使它们在翻译成语法时成为一件麻烦事。最简单的方法是将这些(可能的)分隔符包含在您的值规则中,并在将分隔符和值匹配在一起后,从中除去分隔符字符
一个小演示:
JavaProperties.g
以上语法可以通过课堂测试:
主类
和输入文件:
测试属性
要生成以下输出:
key : `key1`
value : `value 1`
key : `key2`
value : `value 2`
key : `key3`
value : `value3`
key : `ke:=y4`
value : `value 4`
key : `key=5`
value : `=`
key : `key6`
value : `value6`
认识到我的语法只是一个例子:它并没有考虑所有有效的属性文件(有时应该忽略反斜杠,没有Unicode转义,键和值中缺少许多字符)。有关属性文件的完整规范,请参见:
您可能会发现\-转义机制也可以将其他字符放入密钥中,例如带有空格的key\name。还要注意,冒号(:)甚至空格都可以分隔Java.properties文件中的键和值。另外,在下一行的连续值中有一个尾随\的值。我无法使用ANTLR 3.3编译该代码,因为它在JavaPropertiesParser上找不到解析方法。这段代码是为Antlr3.x编写的吗?@Aaron,它在我发布时就可以正常工作(使用3.3版进行测试)。我猜您使用的目标与(默认)Java target.Failes在antlr 3.5上不同,但正如您所说,它是为3.3编写的。我只希望他们不要在小的修改中做大的改动(
import org.antlr.runtime.*;
public class Main {
public static void main(String[] args) throws Exception {
ANTLRStringStream in = new ANTLRFileStream("test.properties");
JavaPropertiesLexer lexer = new JavaPropertiesLexer(in);
CommonTokenStream tokens = new CommonTokenStream(lexer);
JavaPropertiesParser parser = new JavaPropertiesParser(tokens);
parser.parse();
}
}
key1 = value 1
key2:value 2
key3 :value3
ke\:\=y4=v\
a\
l\
u\
e 4
key\=5==
key6 value6
key : `key1`
value : `value 1`
key : `key2`
value : `value 2`
key : `key3`
value : `value3`
key : `ke:=y4`
value : `value 4`
key : `key=5`
value : `=`
key : `key6`
value : `value6`