java - 使用 JavaCC 解析自定义语法时出现问题

标签 java parsing compiler-construction javacc

我正在使用 JavaCC 编写一个解析器。这是我目前的进展:

PARSER_BEGIN(Compiler)

public class Compiler {
    public static void main(String[] args) {
        try {
            (new Compiler(new java.io.BufferedReader(new java.io.FileReader(args[0])))).S();
            System.out.println("Syntax is correct");
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }
}

PARSER_END(Compiler)

<DEFAULT, INBODY> SKIP:  { " " | "\t" | "\r" }
<DEFAULT> TOKEN: { "(" | ")" |  <ID: (["a"-"z","A"-"Z","0"-"9","-","_"])+ > | "\n" : INBODY }
<DEFAULT> TOKEN: { <#RAND: (" " | "\t" | "\r")* > | <END: <RAND> "\n" <RAND> ("\n" <RAND>)+ > }
<INBODY>  TOKEN: { <STRING: (~["\n", "\r"])*> : DEFAULT }

void S(): {}
{
    (Signature() "\n" Body() (["\n"] <EOF> | <END> [<EOF>]) )+
}

void Signature(): {}
{
    "(" <ID> <ID> ")"
}

void Body(): {}
{
    <STRING> ("\n" <STRING> )*
}

我的目标是解析如下所示的语言:

(test1 pic1)
This line is a <STRING> token
After the last <STRING> one empty line is necessary

(test2 pic1)
String1
It is also allowed to have an arbitrary number (>=1) of empty lines




(test3 pic1)
String1
String2

(test4 pic1)
String1
String2
An arbitrary number (also zero) of empty lines follow till <EOF>

它几乎工作正常,但我现在面临的问题如下:

在解析文本的末尾(如上面的示例中所述)允许有任意数量(包括零)的空行,直到 <EOF> 。如果我之前没有空行<EOF>它按预期工作(它打印“语法正确”)。如果我在 <EOF> 之前至少有两行空行它也按预期工作(它打印“语法正确”)。如果 <EOF> 之前只有一个空行它还应该打印“语法正确”。但我得到以下异常堆栈跟踪:

ParseException: Encountered "<EOF>" at line 19, column 9.
Was expecting:
    <STRING> ...

        at Compiler.generateParseException(Compiler.java:284)
        at Compiler.jj_consume_token(Compiler.java:217)
        at Compiler.Body(Compiler.java:83)
        at Compiler.S(Compiler.java:18)
        at Compiler.main(Compiler.java:6)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at com.simontuffs.onejar.Boot.run(Boot.java:340)
        at com.simontuffs.onejar.Boot.main(Boot.java:166)

有人知道问题可能是什么吗?

更新:

换行

(Signature() "\n" Body() (["\n"] <EOF> | <END> [<EOF>]) )+

(Signature() "\n" Body() (<EOF> | <END> [<EOF>]) )+

产生相同的行为。看来["\n"] (由于某种原因)完全被忽略。

最佳答案

我找到了问题的核心。换线

<STRING> ("\n" <STRING> )*

<STRING> (LOOKAHEAD(2) "\n" <STRING> )*

解决了问题。

它只需要一个本地LOOKAHEAD(2)

关于java - 使用 JavaCC 解析自定义语法时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50538219/

相关文章:

java - In-App Review 调用 Log 但不发起对话

java - Exif 数据读 写

string - 使用lua解析代码语法?

javascript - 从服务器获取时,Angularjs 中的 JSON 解析错误,但静态时则不然

c - 如果没有使用头文件中包含的函数,编译器是否仍然编译这个文件?

c++ - 从终端编译框架(cppunit、boost、++)以使用 Xcode 4.6

java - 匹配 <c :if > conditional variable names? 的正则表达式模式

java - 使用 Spring Boot 监听消息队列 SQS 不适用于标准配置

python - 使python变量三引号样式

c# - 使用默认参数重载构造函数