是否有人知道在线资源,我可以找到如何使用Boost :: Spirit?编写简单的表达式解析器.
我不一定需要评估表达式,但我需要解析它并能够返回一个布尔值来指示表达式是否可解析(例如括号不匹配等).
我需要解析器能够识别函数名称(例如foo和foobar),所以这也是帮助我学习编写BNF表示法的有用示例.
表达式将是常规算术方程,即包括以下符号:
我有以下代码:
std::string test("1.1");
std::pair<int, int> d;
bool r = qi::phrase_parse(
test.begin(),
test.end(),
qi::int_ >> '.' >> qi::int_,
space,
d
);
Run Code Online (Sandbox Code Playgroud)
所以我试图解析字符串测试并将结果放在std :: pair d中.但是它没有用,我怀疑它与复合属性规则有关.
有关如何使其工作的任何提示?
编译器错误如下:
错误:没有匹配函数来调用'std :: pair :: pair(const int&)'
我正在编写一个解析器,用于使用缩进等非常复杂的配置文件.我决定使用Lex将输入分解为令牌,因为它似乎使生活更轻松.问题是我找不到任何使用Qi错误报告工具(on_error)的示例,其中解析器使用令牌流而不是字符进行操作.
要使用的错误处理程序on_error需要一些能够准确指示错误在输入流中的位置.所有示例都只是std::string从迭代器对构造并打印出来.但是如果使用Lex,则迭代器是标记序列的迭代器,而不是字符.在我的程序中,这导致std::string在我注意到无效的迭代器类型之前挂起构造函数.
据我所知,令牌可以将输入流的一对迭代器作为其值.这是默认属性类型(如果类型是这样lex::lexertl::token<>).但是,如果我想我的令牌包含一些解析(更多有用的int,std::string等等),这些迭代器都将丢失.
如何在使用带Qi的Lex时生成指示输入流中位置的人性化错误消息?有这种用法的例子吗?
谢谢.
我(经常)面临着必须解析文本数据文件的任务 - 在"每个人"使用XML之前使用的文本结构化数据表示 - 这是某种行业标准.(这些太多了.)
无论如何,基本任务总是采用文本文件并填充某种数据结构中的内容,以便我们的C++代码可以对信息做些什么.
现在,我已经手工实现了一些简单的(并且非常多样的)解析器,并且我几乎没有鄙视.:-)
所以 - 我想知道当我想要将结构化文本数据"解析"为内存中表示时的当前技术水平(想想:任意语言的XML数据绑定).
到目前为止我发现的是" 你推荐什么解析器生成器 ",但我不太确定我是在使用解析器生成器(如ANTLR)之后.
明显的候选人似乎是pegtl和Boost.Spirit,但他们似乎都很复杂(但至少他们是语言),上次我尝试过Spirit,编译错误让我疯狂.(并且pegtl需要兼容C++ 11的编译器,这仍然是一个问题(VC++ 2005).)
所以我错过了一个简单的解决方案,只是为了得到类似的东西
/begin COMPU_METHOD
DEC " Decimal value"
RAT_FUNC
"%3.0"
"dec"
COEFFS 0 1.000000 0.000000 0 0.000000 1.000000
/end COMPU_METHOD
Run Code Online (Sandbox Code Playgroud)
进入C++数据结构?(这只是这个文件的一部分可能看起来的任意例子.对于这种格式,我可以(并且可能应该)购买一个库来解析它,因为它足够广泛 - 对于所有格式我都不是这样的情况遭遇.)
- 或者我应该选择 Boost.Spirit 的复杂性?
我试图使用Boost Spirit X3指令重复一个可变的重复因子.基本思想是标头+有效负载,其中标头指定有效负载的大小.一个简单的例子"3 1 2 3"被解释为header = 3,data = {1,2,3}(3个整数).
我只能从精神qi文档中找到例子.它使用boost phoenix引用来包装变量因子:http://www.boost.org/doc/libs/1_50_0/libs/spirit/doc/html/spirit/qi/reference/directive/repeat.html
std::string str;
int n;
test_parser_attr("\x0bHello World",
char_[phx::ref(n) = _1] >> repeat(phx::ref(n))[char_], str);
std::cout << n << ',' << str << std::endl; // will print "11,Hello World"
Run Code Online (Sandbox Code Playgroud)
我为精神x3写了以下简单的例子,没有运气:
#include <boost/spirit/home/x3.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <string>
#include <iostream>
namespace x3 = boost::spirit::x3;
using x3::uint_;
using x3::int_;
using x3::phrase_parse;
using x3::repeat;
using x3::space;
using std::string;
using std::cout;
using std::endl;
int main( int argc, char **argv )
{ …Run Code Online (Sandbox Code Playgroud) 我目前仍然坚持使用boost spirit x3解析的规则.对于我要解析的内容,这是te EBNF(使用精神列表中的%运算符):
type ::= class_type | lambda_type
lambda_type ::= more_arg_lambda | one_arg_lambda
more_arg_lambda ::= "(", type%",", ")", "=>", type
one_arg_lambda ::= type, "=>", type <- here is the left recursion
class_type ::= identifier%"::", ["<", type%",", ">"]
Run Code Online (Sandbox Code Playgroud)
usng boost spirit x3,我试图解析下面的struct/variant:
typedef x3::variant<
nil,
x3::forward_ast<LambdaType>,
x3::forward_ast<ClassType>
> Type;
struct LambdaType {
std::vector<Type> parameters_;
Type return_type_;
};
struct ClassType{
std::vector<std::string> name_;
std::vector<Type> template_args_;
};
Run Code Online (Sandbox Code Playgroud)
我有一个关于我目前在这里尝试的实例,它不起作用,我也尝试改变变体解析器的顺序,它没有帮助,我得到无尽的回忆,或者没有我期望(或希望)的行为.任何人都可以帮我调试这个解析器吗?我想我在解析器中有一些类型的左递归,是否有机会避免这种情况,或者没有机会重写语法?这个gramar甚至可以用boost spirit x3解析吗?
编辑:
我设法在这个语法中消除了左递归.现在te语法如下:
type ::= class_type | lambda_type
lambda_type ::= more_arg_lambda | …Run Code Online (Sandbox Code Playgroud) 当我尝试编译它时,我有大量的Boost/Spirit元程序正在吹gcc的堆栈.
如何增加gcc的堆栈大小,以便编译该程序?
注意:没有无限递归,但有足够的偶然递归来耗尽gcc的堆栈.
我尝试使用Boost Spirit为一个小编程语言实现一个Lexer.
我必须得到一个令牌的值,我得到一个bad_get异常:
在抛出'boost :: bad_get'的实例后调用终止
what():boost :: bad_get:失败的值得到使用boost :: get Aborted
这样做时我得到了这个例外:
std::string contents = "void";
base_iterator_type first = contents.begin();
base_iterator_type last = contents.end();
SimpleLexer<lexer_type> lexer;
iter = lexer.begin(first, last);
end = lexer.end();
std::cout << "Value = " << boost::get<std::string>(iter->value()) << std::endl;
Run Code Online (Sandbox Code Playgroud)
我的词法分析器定义如下:
typedef std::string::iterator base_iterator_type;
typedef boost::spirit::lex::lexertl::token<base_iterator_type, boost::mpl::vector<unsigned int, std::string>> Tok;
typedef lex::lexertl::actor_lexer<Tok> lexer_type;
template<typename L>
class SimpleLexer : public lex::lexer<L> {
private:
public:
SimpleLexer() {
keyword_for = "for";
keyword_while = "while";
keyword_if = "if";
keyword_else = "else"; …Run Code Online (Sandbox Code Playgroud) 我的boost :: spirit解析器还有另外一个问题.
template<typename Iterator>
struct expression: qi::grammar<Iterator, ast::expression(), ascii::space_type> {
expression() :
expression::base_type(expr) {
number %= lexeme[double_];
varname %= lexeme[alpha >> *(alnum | '_')];
binop = (expr >> '+' >> expr)[_val = construct<ast::binary_op<ast::add>>(_1,_2)]
| (expr >> '-' >> expr)[_val = construct<ast::binary_op<ast::sub>>(_1,_2)]
| (expr >> '*' >> expr)[_val = construct<ast::binary_op<ast::mul>>(_1,_2)]
| (expr >> '/' >> expr)[_val = construct<ast::binary_op<ast::div>>(_1,_2)] ;
expr %= number | varname | binop;
}
qi::rule<Iterator, ast::expression(), ascii::space_type> expr;
qi::rule<Iterator, ast::expression(), ascii::space_type> binop;
qi::rule<Iterator, std::string(), ascii::space_type> varname;
qi::rule<Iterator, …Run Code Online (Sandbox Code Playgroud) 我正在为Java的一个子集编写编译器boost::spirit,用于lexing和解析.在编译词法分析器/解析器阶段期间,编译器消耗1.6GBRAM(g++ (GCC) 4.8.1),但这不是问题,因为这台机器上有足够的内存.
然而,问题在于,当编译器完成并且汇编程序开始运行(GNU assembler (GNU Binutils) 2.23.52.20130604)时,它会崩溃;
as: build/src/ast_generate.o: too many sections (33098)
/tmp/cc0ZyvKK.s: Assembler messages:
/tmp/cc0ZyvKK.s: Fatal error: can't write build/src/ast_generate.o: File too big
as: build/src/ast_generate.o: too many sections (33098)
/tmp/cc0ZyvKK.s: Fatal error: can't close build/src/ast_generate.o: File too big
scons: *** [build/src/ast_generate.o] Error 1
Run Code Online (Sandbox Code Playgroud)
添加'-Os'到我的编译器标志,允许汇编程序处理编译器输出,但正如我所看到的,这只是时间问题,直到我遇到同样的问题,即使使用小优化标志.
检查,使用大小优化的对象文件(ast_generate.o)objdump告诉我,我正在生成pe-x86-64,这是我在Windows上所期望的.
然而,2358生成的部分对我来说是一个震惊.主要是因为似乎已经为每个部分生成了一个部分boost::spirit;
CONTENTS, ALLOC, LOAD, READONLY, DATA, LINK_ONCE_DISCARD
...
60 .pdata$_ZNK5boost5lexer6detail8end_node9unique_idEv 0000000c 0000000000000000 …Run Code Online (Sandbox Code Playgroud) boost-spirit ×10
c++ ×10
boost ×3
parsing ×3
gcc ×2
dataformat ×1
expression ×1
lex ×1
object-files ×1
sections ×1