Lemon LALR 解析器的简单语法
我已经被这个问题困扰了一段时间了。我想解析一些简单的东西:
喜欢:word1 word2 .. wordN 讨厌:word1 word2 .. wordN
我正在使用 Lemon+Flex。目前我的语法看起来像这样:
%left LIKES MOODS FROM HATES INFO.
%syntax_error {
std::cout << "Syntax error!" << std::endl;
}
final ::= likes_stmt.
final ::= hates_stmt.
likes_stmt ::= LIKES list(A). { Data *data=Data::getInstance();data->likes.push_back(A);}
hates_stmt ::= HATES list(A). { Data *data=Data::getInstance();data->hates.push_back(A);}
list ::= likes_stmt VALUE(A). { Data *data=Data::getInstance();data->likes.push_back(A);}
list ::= hates_stmt VALUE(A). { Data *data=Data::getInstance();data->hates.push_back(A); }
list(A) ::= VALUE(B). {A=B;}
但这仅适用于前两个单词。显然我做错了什么,可能是在递归定义中?如有任何提示,我们将不胜感激:)
I've been stuck with this since a while now. I want to parse something as simple as:
LIKES: word1 word2 .. wordN HATES: word1 word2 .. wordN
I am using Lemon+Flex. At the moment my Grammar looks something like this :
%left LIKES MOODS FROM HATES INFO.
%syntax_error {
std::cout << "Syntax error!" << std::endl;
}
final ::= likes_stmt.
final ::= hates_stmt.
likes_stmt ::= LIKES list(A). { Data *data=Data::getInstance();data->likes.push_back(A);}
hates_stmt ::= HATES list(A). { Data *data=Data::getInstance();data->hates.push_back(A);}
list ::= likes_stmt VALUE(A). { Data *data=Data::getInstance();data->likes.push_back(A);}
list ::= hates_stmt VALUE(A). { Data *data=Data::getInstance();data->hates.push_back(A); }
list(A) ::= VALUE(B). {A=B;}
But this only works for first 2 words. Clearly I am doing something wrong , probably in the recursive definition ? Any heads up is appreciated :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
@crozzfire,Ira 为您原来的问题提供了正确的答案,请考虑投票。
让我回答这个问题,并提出将解析值分成两个列表的附加要求。不要创建不同的规则来解析这些列表,因为两种情况下列表的语法是相同的。您需要的是一个标志来指示列表前面是否找到了“喜欢”或“讨厌”。 Lemon 的
Parse
函数的第四个参数最适合这种需求。请参阅 Lemon 文档 的“解析器接口”部分。下面是更新的 Ira 语法,用于设置和检查此类标志变量。请注意,规则
set_likes_state
和set_hites_state
需要放置在 LIKES 和 HATES 令牌之前,以便在令牌减少时执行关联操作。@crozzfire, Ira provided correct answer for your original question, consider voting for it.
Let me answer to the question with you additional requirement to separate parsed values into two lists. Don't create different rules for parsing of these lists since the grammar of list is the same for both cases. What you need is a flag to indicate whether LIKES or HATES was found in front of list. The 4th parameter of Lemon's
Parse
function suits best for this needs. See "The Parser Interface" section of Lemon documentation.Below is updated Ira's grammar that sets and check such flag variable. Take note that rules
set_likes_state
andset_hites_state
need to be placed just before LIKES and HATES token to have associated action executed when tokens are reduced.在我看来,您的 likes_stmt 是根据列表定义的,而列表是根据喜欢定义的。我很惊讶它对任何单词都有效。可能是我不理解 LEMON 语法(我肯定不明白 list(A) 位),但 BNF 语法往往非常相似。
我希望你的语法看起来更像是:
当然,这只会识别一个 LIKES 短语或一个 HATES 短语,但不能同时识别或按问题第二行所暗示的顺序识别。
It looks to me that your likes_stmt is defined in terms of list, and list is defined in terms of likes. I'm surprised it works for any words at all. It could be that I don't understand LEMON syntax (I sure don't get the list(A) bit), but grammars BNFs tend to be pretty similar.
I'd expect your grammar to look more like:
Of course this would only recognize one LIKES phrase, or one HATES phrase, but not both that same time or in order as implied by line 2 of your question.