java - 我可以使用 Antlr 创建的词法分析器/解析器来解析 PDDL 文件并将数据返回给 Java 程序吗?

标签 java antlr pddl

我是 Antlr 的新手,但之前使用过 Flex/Bison。我想知道我想用 Antlr 做的事情是否可行。

我想使用 Antlr 解析 PDDL 文件,并在我编写的 Java 类中构建我自己的 PDDL 文件内容表示,该类是我在解析 PDDL 文件时编写的(在规则的操作中?)。文件解析完成后,我想将文件内容的对象表示返回给 Java 程序以运行其他操作。

所以基本上,我想从 Java 程序内部对 PDDL 文件调用 Antler 生成的 PDDL 解析器,并让它向主 Java 程序返回一个描述 PDDL 文件的对象。

这可能吗?我曾尝试查看文档,但没有找到好的答案。

非常感谢。

最佳答案

So essentially, I want to invoke an Antler produced PDDL parser on a PDDL file from inside a Java program and have it return an object that describes the PDDL file to the main Java program.

Is this possible?

当然可以。

首先,您需要在 (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> .这可以通过在语法规则中嵌入“ Action ”来完成,如下所示:

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]

关于java - 我可以使用 Antlr 创建的词法分析器/解析器来解析 PDDL 文件并将数据返回给 Java 程序吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3818442/

相关文章:

planning - 为什么 PDDL 编译不正确并导致解析错误?

java - DB2 JDBC 驱动程序(类型 4)在 Execute() 上挂起

c# - 用于解析规则的 C# 产品私有(private)方法的 ANTLR

java - 在 maven 中构建 scala-java-antlr 项目会导致运行时出现 ClassDefNotFoundError

ANTLR4 - 使用上下文按顺序访问 token 组

artificial-intelligence - PDDL AI 规划中的一个错误

error-handling - 使用计划程序运行问题文件时出现“Undeclared requirements”错误

java - 在java中隐藏标签页眉

java - Spring RestController 方法返回状态 403

java - 实例变量可以在java中声明为静态变量吗