ANTLR 绑定问题

发布于 2024-08-21 13:47:16 字数 474 浏览 2 评论 0原文

我有这样的字符串:

`(val1, val2, val3)`

我有 ANTLR 语法来解析这段代码:

grammar TEST;

tokens {
 ORB = '(';
 CRB = ')';
 COMA = ',';
}

@members{

}
/*Parser rule*/
mainRule 
    :    ORB WORD (COMA WORD)* CRB;

/*Lexer rule*/

WORD    :    ('a'..'z'|'A'..'Z'|'0'..'9')+;

WS      :   ( '\t' | ' ' | '\r' | '\n'| '\u000C' )+ { $channel = HIDDEN; };

现在我需要将所有 WORD 映射到 Java 中。当目标令牌包含在括号中时,如何绑定值?

非常感谢!

I have strings like this:

`(val1, val2, val3)`

And I have ANTLR grammar to parse this code:

grammar TEST;

tokens {
 ORB = '(';
 CRB = ')';
 COMA = ',';
}

@members{

}
/*Parser rule*/
mainRule 
    :    ORB WORD (COMA WORD)* CRB;

/*Lexer rule*/

WORD    :    ('a'..'z'|'A'..'Z'|'0'..'9')+;

WS      :   ( '\t' | ' ' | '\r' | '\n'| '\u000C' )+ { $channel = HIDDEN; };

Now I need to map all WORDs into Java. How can I bind value when target token embraced into brackets?

Many thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

夏末染殇 2024-08-28 13:47:16

与 JS Bangs 的答案几乎相同,只是这里有一个完整的 SSCCE 你可以编译和运行,我展示了如何可以“标记”您的令牌并访问它们以将它们放入 mainRule 返回的列表中。另请注意,init 前面需要有一个 @ 符号(至少 ANTLR v3 需要它)。

grammar Test;

@parser::members {
  public static void main(String[] args) throws Exception {
    String text = "(a, bb ,  ccc )";
    ANTLRStringStream in = new ANTLRStringStream(text);
    TestLexer lexer = new TestLexer(in);
    CommonTokenStream tokens = new CommonTokenStream(lexer);
    System.out.println(new TestParser(tokens).mainRule());
  }
}

mainRule returns [List<String> words]
@init{$words = new ArrayList<String>();}
  :  '(' w=WORD {$words.add($w.text);} (',' w=WORD {$words.add($w.text);} )* ')'
  ;

WORD
  :  ('a'..'z'|'A'..'Z'|'0'..'9')+
  ;

WS
  :  ( '\t' | ' ' | '\r' | '\n'| '\u000C' )+ { $channel = HIDDEN; }
  ;

然后:

bart@hades:~/Temp$ java -cp antlr-3.2.jar org.antlr.Tool Test.g
bart@hades:~/Temp$ javac -cp antlr-3.2.jar *.java
bart@hades:~/Temp$ java -cp .:antlr-3.2.jar TestParser
[a, bb, ccc]
bart@hades:~/Temp$ 

在 Windows 上,上面的命令几乎相同,只需像这样运行 TestParser:(

java -cp .;antlr-3.2.jar TestParser

有一个分号而不是常规冒号)

Pretty much the same as JS Bangs' answer, only here's a complete SSCCE you can compile and run and I showed how you can "label" your tokens and access them to put them in the List the mainRule is returning. Also note that the init needs an @ sign in front of it (at least ANTLR v3 expects it).

grammar Test;

@parser::members {
  public static void main(String[] args) throws Exception {
    String text = "(a, bb ,  ccc )";
    ANTLRStringStream in = new ANTLRStringStream(text);
    TestLexer lexer = new TestLexer(in);
    CommonTokenStream tokens = new CommonTokenStream(lexer);
    System.out.println(new TestParser(tokens).mainRule());
  }
}

mainRule returns [List<String> words]
@init{$words = new ArrayList<String>();}
  :  '(' w=WORD {$words.add($w.text);} (',' w=WORD {$words.add($w.text);} )* ')'
  ;

WORD
  :  ('a'..'z'|'A'..'Z'|'0'..'9')+
  ;

WS
  :  ( '\t' | ' ' | '\r' | '\n'| '\u000C' )+ { $channel = HIDDEN; }
  ;

And then:

bart@hades:~/Temp$ java -cp antlr-3.2.jar org.antlr.Tool Test.g
bart@hades:~/Temp$ javac -cp antlr-3.2.jar *.java
bart@hades:~/Temp$ java -cp .:antlr-3.2.jar TestParser
[a, bb, ccc]
bart@hades:~/Temp$ 

On Windows the commands above are pretty much the same, only run your TestParser like this:

java -cp .;antlr-3.2.jar TestParser

(there's a semi-colon instead of a regular colon)

羅雙樹 2024-08-28 13:47:16

抱歉,您能详细说明一下您想要做什么吗?
据我了解,您想将每个单词绑定到一个 java 变量,对吗?

words+=WORD (COMA words+=WORD)* {$words}

在这里,您定义一个标签 words (实际上是一个列表),并使用 += 语法将每次出现的 WORD 添加到该标签。然后,您可以参考该标签,如图所示 $words

查看 ANTLR 文档并查找标签。
如果你想用你的解析器做一些复杂的事情,我推荐 Terrence Parr 的关于 ANTLR 的书。它对解析的一般主题有一个非常好的介绍性章节,是 ANTLR 的最佳参考。

华泰

Sorry, could you elaborate a bit on what you are trying to do?
As I get it you want to bind each word to a java variable, correct?

words+=WORD (COMA words+=WORD)* {$words}

Here you define a label words (which is actually a list) and add every occurence of WORD to that label using the += syntax. You can then refer to this label as shown $words

Have a look at the ANTLR-Documentation and look for labels.
If you want to do something sophisticated with your parser I recommend Terrence Parr's book on ANTLR. It has a very good introducory chapter to the general topic of parsing and is the best reference for ANTLR.

HTH

等往事风中吹 2024-08-28 13:47:16

您可以使用 .text 属性获取匹配标记的文本值。像这样:

 string s = $WORD.text

根据您的整体语法应该做什么,将 $WORD.text 字符串添加到内部列表、将其传递给其他函数或将其转换为mainRule 的返回值。例如,如果您希望 mainRule 返回已解析字符串的列表,您可以编写以下内容:

mainRule returns [List strings] @init { $strings = new Vector(); }:
    ORB 
    WORD { $strings.add($WORD.text); } 
    ( COMMA WORD { $strings.add($WORD.text); } )*
    CRB
    ;

You can get the textual value of a matched token with the .text property. Like this:

 string s = $WORD.text

Depending on what your overall grammar is supposed to do, it may be proper to add the $WORD.text string to an internal list, pass it to some other function, or to turn it into the return value from mainRule. For example, if you want mainRule to give you back the list of parsed strings, you can write the following:

mainRule returns [List strings] @init { $strings = new Vector(); }:
    ORB 
    WORD { $strings.add($WORD.text); } 
    ( COMMA WORD { $strings.add($WORD.text); } )*
    CRB
    ;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文