野牛消除可空非终端之间的减少/减少冲突?

时间:2019-02-28 18:45:58

标签: parsing bison nullable rules reduce-reduce-conflict

我正在使用Bison(AFAIK他们默认使用private List<Message> getMessageID(Gmail service, String query) throws IOException { ListMessagesResponse response = service.users().messages().list("me").setQ(query).execute(); List<Message> messages = new ArrayList<Message>(); while (response.getMessages() != null) { messages.addAll(response.getMessages()); if (response.getNextPageToken() != null) { String pageToken = response.getNextPageToken(); response = service.users().messages().list("me").setQ(query) .setPageToken(pageToken).execute(); } else { break; } } if(messages.isEmpty()) { getMessageID(service, query); } messageID = gson.toJson(messages); return messages; } private Message getEmail(Gmail service, String userId, String messageId) throws IOException { Message message = service.users().messages().get(userId, messageId).execute(); email = message.toString(); return message; } public void getGmailEmail() { try { getMessageID(service, "after: " + unixTime); messageID = messageID.split("\",")[0].substring(8); getEmail(service,"me", messageID); System.out.println("Email received"); emailOrThread = email; } catch (IOException ignored) { } } 解析)。

我的语法是这样的:

LL(1)

现在,function_decl: ID '(' params ')' ':' TYPE ... // body may go here function_call: ID '(' arguments ')' params: ID ':' TYPE | params ',' ID ':' TYPE | %empty arguments: ID | arguments ',' ID | %empty 警告说bison冲突,因为reduce/reduceparams都可以为空(在参数arguments为零的情况下) )。

我的问题是,如何消除(而不是抑制)这种冲突?

尽管有人建议使用不同的解析技术,但我还是想让自己自己清楚一点(我应该这样做)还是忽略它。

1 个答案:

答案 0 :(得分:2)

如果忽略警告,您将得到一个解析器,该解析器无法识别没有参数的函数调用。所以这可能不是一个好主意。

您完全正确地认为,冲突是paramsarguments都产生空字符串的结果。因为解析器在读取)中的func()时只能向前看一个符号a,所以它需要决定是否减少空的params(这将迫使它继续进行{{ 1}})或空的function_decl(它将提交给arguments)。但是直到下一个标记被读取,才知道。

最简单的解决方案是避免空的归约,尽管它会使语法稍微复杂一些。在下文中,function_callparams都不产生空字符串,而argumentsfunction_decl的额外产量则用于识别这些情况。

function_call

之所以起作用,是因为它允许解析器推迟调用和声明之间的决定。 LR解析器可以将决策推迟到必须减少之前。它可以同时保持多个生产,但必须在生产结束时减少生产。


请注意,即使没有冲突,您的原始语法也是错误的。如所写,它允许function_decl: ID '(' params ')' ':' TYPE ... // body may go here function_decl: ID '(' ')' ':' TYPE ... function_call: ID '(' arguments ')' function_call: ID '(' ')' params: ID ':' TYPE | params ',' ID ':' TYPE arguments: ID | arguments ',' ID (或arguments)以任意数量的逗号开头。您的意图不是允许params作为替代基本情况,而是作为替代完整扩展。可选的逗号分隔列表的正确语法需要两个非终结符:

%empty