簡體   English   中英

在JAVA中使用ANTLR從字符串中獲取表達式

[英]Fetching expressions from a string using ANTLR in JAVA

給定一個String like ..

(a+(a+b)), (d*e) :- (ef)

注意:(d * e)和(ef)是不同的表達式。 我如何從該字符串中獲取表達式。 我的語法定義為

parse returns [String value]
  :  addExp {$value=$addExp.value;} EOF
  ;

addExp returns [String value]
  :  multExp {$value=$multExp.value;} (('+' | '-' | '*') multExp{$value+= '+' + $multExp.value;})*
  ;

multExp returns [String value]
  :  atom {$value=$atom.value;} (('*' | '/') atom {$value+=$atom.value;)*
  ;

atom returns [String value]
  :  x=ID {$value=$x.text;}
  |  '(' addExp ')' {$value='('+$addExp.value+')';}
  ;

ID    : 'a'..'z' | 'A'..'Z';

我試過了..

ANTLRStringStream a=new ANTLRStringStream("(a+(a+b)), (d*e) :- (e-f)");
SLexer l=new SLexer(a);
CommonTokenStream c=new CommonTokenStream(l);
SParser p=new Sparser(c);

String exp;
while(exp = p.parse())
{
 System.out.println(exp);
}

我在想類似hasNext()的東西,然后取。

您的詞法分析器規則TEXT可能與一個空字符串匹配,從而導致詞法分析器創建無限數量的令牌。 同樣,您不需要在規則后使用所有這些return語句:您只需在其后添加.text即可獲取解析器(或詞法分析器)規則所匹配的內容。

您可以讓解析器返回List<String> ,或者讓它返回單個String重復調用該解析器規則,直到遇到EOF

一些演示:

grammar T;

@parser::members {
  public static void main(String[] args) throws Exception {
    String src = "likes(a, b) :- likes(a, X), likes(X, b). hates(a, b) " + 
        ":- hates(a,X), hates(X,b). likes(a,b) :- says(god, likes(a,b)).";
    TLexer lexer = new TLexer(new ANTLRStringStream(src));
    TParser parser = new TParser(new CommonTokenStream(lexer));
    List<String> statements = parser.parse();
    for(String s : statements) {
      System.out.println(s);
    }
  }
}

parse returns [List<String> statements]
@init{$statements = new ArrayList<String>();}
  :  (statement {$statements.add($statement.text);} ~TEXT+)+ EOF
  ;

statement
  :  TEXT OPAR params CPAR
  ;

params
  :  (param (COMMA param)*)?
  ;

param
  :  TEXT
  |  statement
  ;

COMMA : ',';
OPAR  : '(';
CPAR  : ')';
TEXT  : ('a'..'z' | 'A'..'Z')+;
SPACE : (' ' | '\t') {$channel=HIDDEN;};
OTHER : . ;

請注意, parse規則中的~TEXT+TEXT以外的一個或多個標記匹配。

如果現在創建一個詞法分析器和解析器並運行TParser類:

* nix / MacOS

java -cp antlr-3.3.jar org.antlr.Tool T.g
javac -cp antlr-3.3.jar *.java
java -cp .:antlr-3.3.jar TParser

要么

視窗

java -cp antlr-3.3.jar org.antlr.Tool T.g
javac -cp antlr-3.3.jar *.java
java -cp .;antlr-3.3.jar TParser

您將看到以下內容打印到控制台:

likes(a, b)
likes(a, X)
likes(X, b)
hates(a, b)
hates(a,X)
hates(X,b)
likes(a,b)
says(god, likes(a,b))

編輯

這是如何返回與List<String>相對的單個String

@parser::members {
  public static void main(String[] args) throws Exception {
    String src = "likes(a, b) :- likes(a, X), likes(X, b). hates(a, b) " + 
        ":- hates(a,X), hates(X,b). likes(a,b) :- says(god, likes(a,b)).";
    TLexer lexer = new TLexer(new ANTLRStringStream(src));
    TParser parser = new TParser(new CommonTokenStream(lexer));
    String s;
    while((s = parser.parse()) != null) {
      System.out.println(s);
    }
  }
}

parse returns [String s]
  :  statement ~(TEXT| EOF)* {$s = $statement.text;}
  |  EOF                     {$s = null;}
  ;

您應該只能夠反復調用句子(),直到輸入結束。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM