我可以使用ANTLR的词法创建/解析器解析PDDL文件,并返回数据到Java程序?

StackOverflow https://stackoverflow.com/questions/3818442

  •  26-09-2019
  •  | 
  •  

我的新的Antlr,但是已经使用的Flex /野牛之前。我想知道如果我想用做ANTLR的是可能的。

我想用ANTLR来解析PDDL文件,并建立我自己的PDDL文件的内容表示在Java类中,我写的PDDL文件进行解析(在规则的行动?)。文件已完成解析后,我要的文件的内容对象表示返回Java程序上运行的其他操作。

所以基本上,我想调用鹿茸生产上的PDDL文件PDDL解析器从一个Java程序中,并使其返回描述PDDL文件到主Java程序的对象。

这是可能的?我试图寻找的文件,但还没有找到一个很好的答案。

非常感谢。

有帮助吗?

解决方案

  

所以基本上,我想调用鹿茸生产上的PDDL文件PDDL解析器从一个Java程序中,并使其返回描述PDDL文件到主Java程序的对象。

     

这是可能的?

不确定

首先,你需要描述你的语言中(ANTLR)语法文件。最简单的是做一个结合语法。一种组合语法将为您的语言的词法和语法分析器。当语言变得更加复杂,最好是这两个分开,但开始时,它会更容易只使用一个(组合)的语法文件。

让我们说的PDDL语言只是一种简单的语言:它是一个或多个数字的连续或者十六进制(0x12FD),八进制(0745)或十进制(12345)符号分隔的空格。这种语言可以在称为PDDL.g以下ANTLR语法文件来描述:

grammar PDDL;

parse
  :  number+ EOF
  ;

number
  :  Hex
  |  Dec
  |  Oct
  ;

Hex
  :  '0' ('x' | 'X') ('0'..'9' | 'a'..'f' | 'A'..'F')+
  ;

Dec
  :  '0'
  |  '1'..'9' ('0'..'9')*
  ;

Oct
  :  '0' '0'..'7'+
  ;

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

在此语法,规则(语法分析,数,六角,...是规则)以大写开始是词法规则。其他的有解析器的规则。

从该语法,可以创建一个词法分析器和解析器这样的:

java -cp antlr-3.2.jar org.antlr.Tool PDDL.g

产生(至少)文件PDDLParser.javaPDDLLexer.java

现在创建一个小的测试类中,你可以使用这些词法和语法分析器类:

import org.antlr.runtime.*;
import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws Exception {
        File source = new File("source.txt");
        ANTLRInputStream in = new ANTLRInputStream(new FileInputStream(source));
        PDDLLexer lexer = new PDDLLexer(in);
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        PDDLParser parser = new PDDLParser(tokens);
        parser.parse();
    }
}

其中source.txt文件的内容可能是这样的:

0xcAfE 0234
66678 0X12 0777

现在编译所有.java文件:

javac -cp antlr-3.2.jar *.java

和运行的主类:

// Windows
java -cp .;antlr-3.2.jar Main

// *nix/MacOS
java -cp .:antlr-3.2.jar Main

如果一切正常,没有被打印到控制台。

现在你说你想让根据你的源文件的内容解析器返回的特定对象。比方说,我们希望我们的语法返回一个List<Integer>。这可以通过在你的语法规则嵌入“动作”这样进行:

grammar PDDL;

parse returns [List<Integer> list]
@init{$list = new ArrayList<Integer>();}
  :  (number {$list.add($number.value);})+ EOF
  ;

number returns [Integer value]
  :  Hex {$value = Integer.parseInt($Hex.text.substring(2), 16);}
  |  Dec {$value = Integer.parseInt($Dec.text);}
  |  Oct {$value = Integer.parseInt($Oct.text, 8);}
  ;

Hex
  :  '0' ('x' | 'X') ('0'..'9' | 'a'..'f' | 'A'..'F')+
  ;

Dec
  :  '0'
  |  '1'..'9' ('0'..'9')*
  ;

Oct
  :  '0' '0'..'7'+
  ;

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

正如你所看到的,你可以让规则返回(returns [Type t]),可如果{}包裹其嵌入普通的Java代码。在@init规则的parse部分被放置在parse文件PDDLParser.java方法的开始。

测试与此类新解析器:

import org.antlr.runtime.*;
import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws Exception {
        File source = new File("source.txt");
        ANTLRInputStream in = new ANTLRInputStream(new FileInputStream(source));
        PDDLLexer lexer = new PDDLLexer(in);
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        PDDLParser parser = new PDDLParser(tokens);
        List<Integer> numbers = parser.parse();
        System.out.println("After parsing :: "+numbers);
    }
}

和你会看到下面的被打印到控制台:

After parsing :: [51966, 156, 66678, 18, 511]

其他提示

这当然是可能的,因为的Antlr被设计以产生然后被调用作为较大系统的一部分的解析器(例如,编译器或一个静态代码分析仪)。

开始与特伦斯帕尔的权威的Antlr参考:构件的领域特定语言。他是ANTLR的作者,也是对语言处理的异常清晰,浅显易懂的老师。

Martin Fowler的领域特定语言用途的Antlr在许多其例子。比如第200页上,他给出了一个简单的“Hello World”例子,其中一个Java程序调用ANTLR来的人一个文件解析迎接,并同时做它发出的问候。这里的地方完成工作(第206页):

class GreetingsLoader. ..
  public void run() {
    try {
      GreetingsLexer lexer = new GreetingsLexer(new ANTLRReaderStream(input));
      GreetingsParser parser = new GreetingsParser(new CommonTokenStream(lexer));
      parser.helper = this;
      parser.script() ;
      if (hasErrors() ) throw new RuntimeException("it all went pear-shaped\n" +
 errorReport() ) ;
    } catch (IOException e) {
      throw new RuntimeException( e) ;
    } catch (RecognitionException e) {
      throw new RuntimeException( e) ;
    }
  }

第三个良好的开端是特伦斯上的DSL 语言实现模式的新。他描述了各种方法来使用ANTLR的,因为比如写一个抽象语法树生成放入编译器。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top