Properties ANTLR解析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

我正在尝试学习ANTLR并为Java属性编写语法。我在这里遇到了一个问题,希望能得到一些帮助

在Java属性中,它有一点奇怪的转义处理。比如说,

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`