ANTLR解析Java属性

| 我正在尝试学习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)
    ;
如果可以实施更好的建议,有什么好的建议? 非常感谢     
已邀请:
并非如此简单。您无法在词法处理级别上处理太多事情,因为许多事情取决于特定的上下文。因此,在词法分析级别,您只能匹配单个字符并在解析器规则中构造键和值。另外,可能的键值分隔符“ 3”和“ 4”以及这些字符可以作为值的开始这一事实,使它们在转换成语法时不易。最简单的方法是将这些(可能)分隔符包含在您的价值规则中,然后将分隔符和值匹配在一起,然后从中剥离分隔符。 一个小演示: JavaProperties.g
grammar JavaProperties;

parse
  :  line* EOF
  ;

line
  :  Space* keyValue
  |  Space* Comment eol
  |  Space* LineBreak
  ;

keyValue
  :  key separatorAndValue eol
     {
       // Replace all escaped `=` and `:`
       String k = $key.text.replace(\"\\\\:\", \":\").replace(\"\\\\=\", \"=\");

       // Remove the  separator, if it exists
       String v = $separatorAndValue.text.replaceAll(\"^\\\\s*[:=]\\\\s*\", \"\");

       // Remove all escaped line breaks with trailing spaces
       v = v.replaceAll(\"\\\\\\\\(\\r?\\n|\\r)[ \\t\\f]*\", \"\").trim();

       System.out.println(\"\\nkey   : `\" + k + \"`\");
       System.out.println(\"value : `\" + v + \"`\");
     }
  ;

key
  :  keyChar+
  ;

keyChar
  :  AlphaNum 
  |  Backslash (Colon | Equals)
  ;

separatorAndValue
  :  (Space | Colon | Equals) valueChar+
  ;

valueChar
  :  AlphaNum 
  |  Space 
  |  Backslash LineBreak
  |  Equals
  |  Colon
  ;

eol
  :  LineBreak
  |  EOF
  ;

Backslash : \'\\\\\';
Colon     : \':\';
Equals    : \'=\';

Comment
  :  (\'!\' | \'#\') ~(\'\\r\' | \'\\n\')*
  ;

LineBreak
  :  \'\\r\'? \'\\n\'
  |  \'\\r\'
  ;

Space
  :  \' \' 
  |  \'\\t\' 
  |  \'\\f\'
  ;

AlphaNum
  :  \'a\'..\'z\'
  |  \'A\'..\'Z\'
  |  \'0\'..\'9\'
  ;
上面的语法可以通过以下类进行测试: Main.java
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();
  }
}
和输入文件: test.properties
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`
意识到我的语法只是一个例子:它不能说明所有有效的属性文件(有时反斜杠应被忽略,没有Unicode转义符,键和值中缺少许多字符)。有关属性文件的完整规范,请参见: http://download.oracle.com/javase/6/docs/api/java/util/Properties.html#load%28java.io.Reader%29     

要回复问题请先登录注册