- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
所以我有以下 qi skipper :
template<typename Iterator> struct verilog_skipper :
public qi::grammar<Iterator> {
verilog_skipper() : verilog_skipper::base_type(skip) {
namespace phx = boost::phoenix;
skip = qi::ascii::space | qi::eol | line_comment;
line_comment = (qi::lit("//") >> *(qi::char_ - qi::eol) >> *(qi::eol));
}
qi::rule<Iterator> skip;
qi::rule<Iterator> line_comment;
};
和下面的qi语法:
template <typename Iterator,
typename Skipper = verilog_skipper<Iterator> struct verilog_grammer :
qi::grammar<Iterator, Skipper> {
verilog_ast ckt_ast;
verilog_grammer()
: verilog_grammer::base_type(module) {
namespace phx = boost::phoenix;
module = (module_definition >> statements >> qi::lit("endmodule"));
statements = statement % ';';
statement = (input_wires | instance);
module_definition = (qi::lit("module") >> ident >> qi::char_('(')
>> ident_list >> qi::char_(')') >> ';' );
input_wires = (qi::lit("input") >> ident_list);
instance = (ident >> ident >>
qi::char_('(') >> connection_pair_list >> qi::char_(')'));
connection_pair_list = connection_pair % ',';
connection_pair = (qi::char_('.')[phx::bind(&found_smth)]
>> ident >> qi::char_('(') >> ident >> qi::char_(')'));
ident_list = ident % ',';
ident = (qi::char_("a-zA-Z_") >> *qi::char_("a-zA-Z_0-9"));
}
qi::rule<Iterator, Skipper> module;
qi::rule<Iterator, Skipper> module_definition;
qi::rule<Iterator, Skipper> statements;
qi::rule<Iterator, Skipper> statement;
qi::rule<Iterator, Skipper> instance;
qi::rule<Iterator, Skipper> input_wires;
qi::rule<Iterator, std::vector<std::pair<std::string, std::string> >(), Skipper> connection_pair_list;
qi::rule<Iterator, std::pair<std::string, std::string>(), Skipper> connection_pair;
qi::rule<Iterator, std::vector<std::string>(), Skipper> ident_list;
qi::rule<Iterator, std::string(), Skipper> ident;
};
我已将 found_smth
函数绑定(bind)到语法中的点字符。我觉得规则是正确的,但我无法匹配以下输入中的任何 connection_pairs 并且解析失败,因为迭代器无法相互访问:
module mymod (A, B);
input A, B;
XOR21 gatexor5 (.A(B) , .C(D));
endmodule
skipper 是否正在消耗点数?我应该立即得到一场比赛,对吗?谁能帮我发现问题?
这是我的主要
代码:
typedef verilog_skipper<std::string::const_iterator> verilog_skipper;
typedef verilog_grammer<std::string::const_iterator, verilog_skipper> verilog_grammar;
verilog_grammar vg; // Our grammar
verilog_skipper vg_skip; // Our grammar
using boost::spirit::ascii::space;
std::string::const_iterator iter = storage.begin();
std::string::const_iterator end = storage.end();
bool r = qi::phrase_parse(iter, end, vg, vg_skip);
if (r && iter == end)
{
std::cout << "-------------------------\n";
std::cout << "Parsing succeeded\n";
std::cout << "-------------------------\n";
return 0;
}
最佳答案
一些事情。
你需要复习 skipper 和词位:
具体来说,qi::eol
是 qi::space
的一部分(不是 qi::blank
)。我会将 skipper 简单地指定为
skip = qi::ascii::space | line_comment;
line_comment = "//" >> *(qi::char_ - qi::eol) >> (qi::eol|qi::eoi);
更具体地说,您将/需要/确保标识符是一个词素。最简单的方法是从规则声明中删除 skipper 。否则 "a b\nc"
是标识符 "abc"
的完全有效拼写。
// lexemes
qi::rule<Iterator, std::string()> primitive_gate, ident;
接下来您的示例显示每个 以';'
结尾的语句。但是你的语法说:
statements = statement % ';';
这将允许 "S1"
、"S1;S2"
,...但不允许 "S1;"
。有几种方法可以修复它。最简单的似乎是
statements = +(statement >> ';'); // require exactly one `;` always
或者,如果 "S1;;;;"
也是可以接受的,你可能会想说
statements = +(statement >> +qi::lit(';')); // require at least one `;` always
请注意,尽管这将不接受 ";;;S1;;"
,也不会像您预期的那样接受 ""
。我经常使用的模式是可选元素列表:
statements = -statement % ';'; // simple and flexible
它有一个很好的方式来接受 ""
, ";"
, ";;"
, "S1"
、";;S1;"
等。请注意,它不如像
statements = *(*qi::lit(';') >> statement >> +qi::lit(';')); // require exactly one `;` always
我注意到您使用 qi::char_('(')
(和类似的)将在合成属性中公开匹配的字符。高度不太可能 这就是你的意思。使用 qi::lit('(')
代替,或者实际上,在你的解析器表达式中使用裸字符/字符串文字将 boost 它们解析器表达式¹
考虑使用 BOOST_SPIRIT_DEBUG 来深入了解您的语法在做什么
封装您的 skipper ,因为调用者不应该为此烦恼,并且您可能不希望语法的用户能够更改 skipper (这可能会破坏整个语法)。
考虑使用符号而不是列出关键字,例如:
primitive_gate = qi::lit("nand") | "nor" | "and" | "or" | "xor" |
"xnor" | "buf" | "not";
注意排序和关键字匹配。如果你解析一个标识符,像 nand
这样的关键字会匹配。但是,如果您有一个像 xor21
这样的标识符,则关键字 xor
将首先匹配。您可能想要/需要防范这种情况 ( How to parse reserved words correctly in boost spirit )
请注意,除非您使用 operator%=
将解析器表达式分配给规则。
应用以上...:
#define BOOST_SPIRIT_DEBUG
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/repository/include/qi_distinct.hpp>
#include <boost/fusion/adapted.hpp>
namespace qi = boost::spirit::qi;
static void found_smth() { std::cout << __PRETTY_FUNCTION__ << "\n"; }
template <typename Iterator> struct verilog_skipper : qi::grammar<Iterator> {
verilog_skipper() : verilog_skipper::base_type(skip) {
skip = qi::ascii::space | line_comment;
line_comment = "//" >> *(qi::char_ - qi::eol) >> (qi::eol|qi::eoi);
}
private:
qi::rule<Iterator> skip;
qi::rule<Iterator> line_comment;
};
template <typename Iterator>
struct verilog_grammar : qi::grammar<Iterator> {
//verilog_ast ckt_ast;
typedef verilog_skipper<Iterator> Skipper;
verilog_grammar() : verilog_grammar::base_type(start) {
namespace phx = boost::phoenix;
using boost::spirit::repository::qi::distinct;
auto kw = distinct(qi::char_("a-zA-Z_0-9"));
start = qi::skip(qi::copy(skipper)) [module];
module = (module_definition >> statements >> kw["endmodule"]);
module_definition = (kw["module"] >> ident >> '(' >> ident_list >> ')' >> ';');
statements = -statement % ';';
statement = input_wires | output_wires | internal_wires | primitive | instance;
input_wires = kw["input"] >> ident_list;
output_wires = kw["output"] >> ident_list;
internal_wires = kw["wire"] >> ident_list;
primitive = primitive_gate >> ident >> '(' >> ident_list >> ')';
instance = ident >> ident >> '(' >> connection_pair_list >> ')';
connection_pair_list = connection_pair % ',';
// NOTE subtle use of `operator%=` in the presence of a semantic action
connection_pair %= (qi::lit('.')[phx::bind(&found_smth)] >> ident
>> '(' >> ident >> ')');
ident_list = ident % ',';
ident = (qi::char_("a-zA-Z_") >> *qi::char_("a-zA-Z_0-9"));
primitive_gate = qi::raw[kw[primitive_gate_]];
BOOST_SPIRIT_DEBUG_NODES(
(module)(module_definition)(statements)(statement)
(primitive)(primitive_gate)(instance)
(output_wires)(input_wires)(input_wires)
(connection_pair_list)(connection_pair)(ident_list)(ident)
)
}
private:
qi::rule<Iterator> start;
qi::rule<Iterator, Skipper> module;
qi::rule<Iterator, Skipper> module_definition;
qi::rule<Iterator, Skipper> statements;
qi::rule<Iterator, Skipper> statement;
qi::rule<Iterator, Skipper> primitive;
qi::rule<Iterator, std::string()> primitive_gate;
qi::rule<Iterator, Skipper> instance;
qi::rule<Iterator, Skipper> output_wires;
qi::rule<Iterator, Skipper> input_wires;
qi::rule<Iterator, Skipper> internal_wires;
qi::rule<Iterator, std::vector<std::pair<std::string, std::string> >(), Skipper> connection_pair_list;
qi::rule<Iterator, std::pair<std::string, std::string>(), Skipper> connection_pair;
qi::rule<Iterator, std::vector<std::string>(), Skipper> ident_list;
// lexemes
qi::rule<Iterator, std::string()> ident;
struct primitive_gate_t : qi::symbols<char> {
primitive_gate_t() { this->add("nand")("nor")("and")("or")("xor")("xnor")("buf")("not"); }
} primitive_gate_;
Skipper skipper;
};
#include <fstream>
int main() {
std::ifstream ifs("input.txt");
using It = boost::spirit::istream_iterator;
It f(ifs >> std::noskipws), l;
bool ok = qi::parse(f, l, verilog_grammar<It>{});
if (ok)
std::cout << "Parsed\n";
else
std::cout << "Parse failed\n";
if (f!=l)
std::cout << "Remaining unparsed '" << std::string(f,l) << "'\n";
}
打印:
void found_smth()
void found_smth()
Parsed
或者启用调试信息(BOOST_SPIRIT_DEBUG
):
<module>
<try>module mymod (A, B);</try>
<module_definition>
<try>module mymod (A, B);</try>
<ident>
<try>mymod (A, B);\n\ninput</try>
<success> (A, B);\n\ninput A, B</success>
<attributes>[[m, y, m, o, d]]</attributes>
</ident>
<ident_list>
<try>A, B);\n\ninput A, B;\n</try>
<ident>
<try>A, B);\n\ninput A, B;\n</try>
<success>, B);\n\ninput A, B;\n\n</success>
<attributes>[[A]]</attributes>
</ident>
<ident>
<try>B);\n\ninput A, B;\n\nXO</try>
<success>);\n\ninput A, B;\n\nXOR</success>
<attributes>[[B]]</attributes>
</ident>
<success>);\n\ninput A, B;\n\nXOR</success>
<attributes>[[[A], [B]]]</attributes>
</ident_list>
<success>\n\ninput A, B;\n\nXOR21</success>
<attributes>[]</attributes>
</module_definition>
<statements>
<try>\n\ninput A, B;\n\nXOR21</try>
<statement>
<try>\n\ninput A, B;\n\nXOR21</try>
<input_wires>
<try>\n\ninput A, B;\n\nXOR21</try>
<input_wires>
<try>\n\ninput A, B;\n\nXOR21</try>
<ident_list>
<try> A, B;\n\nXOR21 gatexo</try>
<ident>
<try>A, B;\n\nXOR21 gatexor</try>
<success>, B;\n\nXOR21 gatexor5</success>
<attributes>[[A]]</attributes>
</ident>
<ident>
<try>B;\n\nXOR21 gatexor5 (</try>
<success>;\n\nXOR21 gatexor5 (.</success>
<attributes>[[B]]</attributes>
</ident>
<success>;\n\nXOR21 gatexor5 (.</success>
<attributes>[[[A], [B]]]</attributes>
</ident_list>
<success>;\n\nXOR21 gatexor5 (.</success>
<attributes>[]</attributes>
</input_wires>
<success>;\n\nXOR21 gatexor5 (.</success>
<attributes>[]</attributes>
</input_wires>
<success>;\n\nXOR21 gatexor5 (.</success>
<attributes>[]</attributes>
</statement>
<statement>
<try>\n\nXOR21 gatexor5 (.A</try>
<input_wires>
<try>\n\nXOR21 gatexor5 (.A</try>
<input_wires>
<try>\n\nXOR21 gatexor5 (.A</try>
<fail/>
</input_wires>
<fail/>
</input_wires>
<output_wires>
<try>\n\nXOR21 gatexor5 (.A</try>
<fail/>
</output_wires>
<primitive>
<try>\n\nXOR21 gatexor5 (.A</try>
<primitive_gate>
<try>XOR21 gatexor5 (.A(B</try>
<fail/>
</primitive_gate>
<fail/>
</primitive>
<instance>
<try>\n\nXOR21 gatexor5 (.A</try>
<ident>
<try>XOR21 gatexor5 (.A(B</try>
<success> gatexor5 (.A(B) , .</success>
<attributes>[[X, O, R, 2, 1]]</attributes>
</ident>
<ident>
<try>gatexor5 (.A(B) , .C</try>
<success> (.A(B) , .C(D));\nen</success>
<attributes>[[g, a, t, e, x, o, r, 5]]</attributes>
</ident>
<connection_pair_list>
<try>.A(B) , .C(D));\nendm</try>
<connection_pair>
<try>.A(B) , .C(D));\nendm</try>
<ident>
<try>A(B) , .C(D));\nendmo</try>
<success>(B) , .C(D));\nendmod</success>
<attributes>[[A]]</attributes>
</ident>
<ident>
<try>B) , .C(D));\nendmodu</try>
<success>) , .C(D));\nendmodul</success>
<attributes>[[B]]</attributes>
</ident>
<success> , .C(D));\nendmodule</success>
<attributes>[[[A], [B]]]</attributes>
</connection_pair>
<connection_pair>
<try> .C(D));\nendmodule\n</try>
<ident>
<try>C(D));\nendmodule\n</try>
<success>(D));\nendmodule\n</success>
<attributes>[[C]]</attributes>
</ident>
<ident>
<try>D));\nendmodule\n</try>
<success>));\nendmodule\n</success>
<attributes>[[D]]</attributes>
</ident>
<success>);\nendmodule\n</success>
<attributes>[[[C], [D]]]</attributes>
</connection_pair>
<success>);\nendmodule\n</success>
<attributes>[[[[A], [B]], [[C], [D]]]]</attributes>
</connection_pair_list>
<success>;\nendmodule\n</success>
<attributes>[]</attributes>
</instance>
<success>;\nendmodule\n</success>
<attributes>[]</attributes>
</statement>
<statement>
<try>\nendmodule\n</try>
<input_wires>
<try>\nendmodule\n</try>
<input_wires>
<try>\nendmodule\n</try>
<fail/>
</input_wires>
<fail/>
</input_wires>
<output_wires>
<try>\nendmodule\n</try>
<fail/>
</output_wires>
<primitive>
<try>\nendmodule\n</try>
<primitive_gate>
<try>endmodule\n</try>
<fail/>
</primitive_gate>
<fail/>
</primitive>
<instance>
<try>\nendmodule\n</try>
<ident>
<try>endmodule\n</try>
<success>\n</success>
<attributes>[[e, n, d, m, o, d, u, l, e]]</attributes>
</ident>
<ident>
<try></try>
<fail/>
</ident>
<fail/>
</instance>
<fail/>
</statement>
<success>\nendmodule\n</success>
<attributes>[]</attributes>
</statements>
<success>\n</success>
<attributes>[]</attributes>
</module>
¹只要表达式中涉及的一个操作数来自气原表达式域
关于c++ - Boost.Qi 规则与 skipper 不匹配 '.' 字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46635994/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!