Java 如何使用ANTLR中的贪婪=false选项访问匹配的属性文本块?

Java 如何使用ANTLR中的贪婪=false选项访问匹配的属性文本块?,java,antlr,grammar,greedy,non-greedy,Java,Antlr,Grammar,Greedy,Non Greedy,我的ANTLR语法中有这样一条规则: COMMENT : '/*' (options {greedy=false;} : . )* '*/' ; COMMENT : '/*' e=((options {greedy=false;} : . )*) '*/' {System.out.println("got: " + $e.text); 此规则只匹配c风格的注释,因此它将接受任意一对/*和*/以及任意文本,并且工作正常 我现在要做的是,当规则匹配时,捕获/*和*/之间的所有文本,使其可供操

我的ANTLR语法中有这样一条规则:

COMMENT :  '/*' (options {greedy=false;} : . )* '*/' ;
COMMENT :  '/*' e=((options {greedy=false;} : . )*) '*/' {System.out.println("got: " + $e.text);
此规则只匹配c风格的注释,因此它将接受任意一对/*和*/以及任意文本,并且工作正常

我现在要做的是,当规则匹配时,捕获/*和*/之间的所有文本,使其可供操作访问。大概是这样的:

COMMENT :  '/*' (options {greedy=false;} : . )* '*/' ;
COMMENT :  '/*' e=((options {greedy=false;} : . )*) '*/' {System.out.println("got: " + $e.text);
这种方法不起作用,在解析过程中,当到达“/”后面的第一个字符时,它会给出“没有可行的替代方案”

我不太清楚是否/如何做到这一点-欢迎提供任何建议或指导,谢谢。

尝试以下方法:

COMMENT :
  '/*' {StringBuilder comment = new StringBuilder();} ( options {greedy=false;} : c=. {comment.appendCodePoint(c);} )* '*/' {System.out.println(comment.toString());};
另一种方法将实际返回StringBuilder对象,以便您可以在程序中使用它:

COMMENT returns [StringBuilder comment]:
  '/*' {comment = new StringBuilder();} ( options {greedy=false;} : c=. {comment.append((char)c);} )* '*/';
试试这个:

COMMENT :
  '/*' {StringBuilder comment = new StringBuilder();} ( options {greedy=false;} : c=. {comment.appendCodePoint(c);} )* '*/' {System.out.println(comment.toString());};
另一种方法将实际返回StringBuilder对象,以便您可以在程序中使用它:

COMMENT returns [StringBuilder comment]:
  '/*' {comment = new StringBuilder();} ( options {greedy=false;} : c=. {comment.append((char)c);} )* '*/';

请注意,您可以简单地执行以下操作:

getText().substring(2, getText().length()-2)
注释上
,因为第一个和最后两个字符始终是
/*
*/

您还可以删除
选项{greedy=false;}:
,因为
*
+
都是不冻结的(尽管没有
它们是贪婪的)(i)

编辑 或者在
注释
标记上使用
setText(…)
立即丢弃
/*
*/
。一个小演示:

文件
T.g

grammar T;

@parser::members {
    public static void main(String[] args) throws Exception {
        ANTLRStringStream in = new ANTLRStringStream(
                "/* abc */   \n" +
                "            \n" + 
                "/*          \n" +
                "   DEF      \n" + 
                "*/            "
        );
        TLexer lexer = new TLexer(in);
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        TParser parser = new TParser(tokens);
        parser.parse();
    }
}

parse
  :  ( Comment {System.out.printf("parsed :: >\%s<\%n", $Comment.getText());} )+ EOF
  ;

Comment
  :  '/*' .* '*/' {setText(getText().substring(2, getText().length()-2));}
  ;

Space
  :  (' ' | '\t' | '\r' | '\n') {skip();}
  ;
语法T;
@解析器::成员{
公共静态void main(字符串[]args)引发异常{
AntlStringStream in=新的AntlStringStream(
“/*abc*/\n”+
“\n”+
“/*\n”+
“DEF\n”+
"*/            "
);
TLexer lexer=新的TLexer(in);
CommonTokenStream令牌=新的CommonTokenStream(lexer);
TParser parser=新的TParser(令牌);
parser.parse();
}
}
作语法分析

:(注释{System.out.printf(“已解析::>\%s请注意,您只需执行以下操作:

getText().substring(2, getText().length()-2)
注释上
,因为第一个和最后两个字符始终是
/*
*/

您还可以删除
选项{greedy=false;}:
,因为
*
+
都是不冻结的(尽管没有
它们是贪婪的)(i)

编辑 或者在
注释
标记上使用
setText(…)
立即丢弃
/*
*/
。一个小演示:

文件
T.g

grammar T;

@parser::members {
    public static void main(String[] args) throws Exception {
        ANTLRStringStream in = new ANTLRStringStream(
                "/* abc */   \n" +
                "            \n" + 
                "/*          \n" +
                "   DEF      \n" + 
                "*/            "
        );
        TLexer lexer = new TLexer(in);
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        TParser parser = new TParser(tokens);
        parser.parse();
    }
}

parse
  :  ( Comment {System.out.printf("parsed :: >\%s<\%n", $Comment.getText());} )+ EOF
  ;

Comment
  :  '/*' .* '*/' {setText(getText().substring(2, getText().length()-2));}
  ;

Space
  :  (' ' | '\t' | '\r' | '\n') {skip();}
  ;
语法T;
@解析器::成员{
公共静态void main(字符串[]args)引发异常{
AntlStringStream in=新的AntlStringStream(
“/*abc*/\n”+
“\n”+
“/*\n”+
“DEF\n”+
"*/            "
);
TLexer lexer=新的TLexer(in);
CommonTokenStream令牌=新的CommonTokenStream(lexer);
TParser parser=新的TParser(令牌);
parser.parse();
}
}
作语法分析
:(注释{System.out.printf(“已解析::>\%s