我正在使用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/reduce
和params
都可以为空(在参数arguments
为零的情况下) )。
我的问题是,如何消除(而不是抑制)这种冲突?
尽管有人建议使用不同的解析技术,但我还是想让自己自己清楚一点(我应该这样做)还是忽略它。
答案 0 :(得分:2)
如果忽略警告,您将得到一个解析器,该解析器无法识别没有参数的函数调用。所以这可能不是一个好主意。
您完全正确地认为,冲突是params
和arguments
都产生空字符串的结果。因为解析器在读取)
中的func()
时只能向前看一个符号a,所以它需要决定是否减少空的params
(这将迫使它继续进行{{ 1}})或空的function_decl
(它将提交给arguments
)。但是直到下一个标记被读取,才知道。
最简单的解决方案是避免空的归约,尽管它会使语法稍微复杂一些。在下文中,function_call
和params
都不产生空字符串,而arguments
和function_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