我试图运行一些简单的解析器来解析[1,11,3,6-4]。基本上,整数列表带有范围符号。
我想将所有内容都放入AST中,而无需进行语义操作。所以我用x3 :: variant。我的代码“似乎”与表达式示例非常相似。但是,它不能在g ++ 6.2下编译。使用clang ++ 6.0确实可以编译,但结果错误。
增强版为1.63。 看来我有一些“移动”或初始化问题。
#include <iostream>
#include <list>
#include <vector>
#include <utility>
#include <boost/spirit/home/x3.hpp>
#include <boost/spirit/home/x3/support/ast/variant.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/adapted/std_pair.hpp>
#include <boost/fusion/include/io.hpp>
namespace ns
{
namespace ast
{
namespace x3 = boost::spirit::x3;
// forward definition
class uintObj;
struct varVec;
// define type
using uintPair_t = std::pair<unsigned int, unsigned int>;
using uintVec_t = std::vector<uintObj>;
// general token value:
class uintObj : public x3::variant <
unsigned int,
uintPair_t
>
{
public:
using base_type::base_type;
using base_type::operator=;
};
struct varVec
{
uintVec_t valVector;
};
}
}
BOOST_FUSION_ADAPT_STRUCT(
ns::ast::varVec,
valVector
)
namespace ns
{
namespace parser
{
// namespace x3 = boost::spirit::x3;
// using namespace x3;
using namespace boost::spirit::x3;
// definition of the range pair:
rule<class uintPair, ast::uintPair_t> const uintPair = "uintPair";
auto const uintPair_def =
uint_
>> '-'
>> uint_
;
rule<class uintObj, ast::uintObj> const uintObj = "uintObj";
auto const uintObj_def =
uint_
| uintPair
;
// define rule definition : rule<ID, attrib>
// more terse definition :
// struct varVec_class;
// using varVec_rule_t = x3::rule<varVec_class, ast::varVec>;
// varVec_rule_t const varVec = "varVec";
// varVec is the rule, "varVec" is the string name of the rule.
rule<class varVec, ast::varVec> const varVec = "varVec";
auto const varVec_def =
'['
>> uintObj % ','
>> ']'
;
BOOST_SPIRIT_DEFINE(
varVec,
uintObj,
uintPair
);
}
}
int main()
{
std::string input ("[1, 11, 3, 6-4]\n");
std::string::const_iterator begin = input.begin();
std::string::const_iterator end = input.end();
ns::ast::varVec result; // ast tree
using ns::parser::varVec; // grammar
using boost::spirit::x3::ascii::space;
bool success = phrase_parse(begin, end, varVec, space, result);
if (success && begin == end)
std::cout << "good" << std::endl;
else
std::cout << "bad" << std::endl;
return 0;
}
答案 0 :(得分:3)
交换uintObj_def
的替代顺序
auto const uintObj_def =
uintPair
| uint_
;
您现在拥有的公式将始终与uint_
匹配,因为uintPair
以有效的uint_
开头。
答案 1 :(得分:1)
mjcaisse的答案指出了我认为您遇到的主要问题。遗漏了一些内容,因此我决定制作一个简化版本以显示解析结果:
import random
import tkinter as tk
from tkinter import *
from tkinter import messagebox
import sqlite3
def conacona():
conn = sqlite3.connect('student.db')
c = conn.cursor()
c.execute("CREATE TABLE IF NOT EXISTS stud (firstname TEXT, secondname TEXT)")
conn.commit()
conn.close()
#oooooooo
main_menu = tk.Tk()
firstname_label = Label(main_menu, text="First name")
firstname_label.pack()
secondname_label = Label(main_menu, text="Second name")
secondname_label.pack()
# First name get
firstname_entry = tk.StringVar()
firstname_entry_entry = Entry(main_menu, textvariable = fn_ent_ent)
firstname_entry_entry.pack()
# Second name get
secondname_entry = tk.StringVar()
secondname_entry_entry = Entry(main_menu, textvariable = sn_ent_ent)
secondname_entry_entry.pack()
def savedata ():
conn = sqlite3.connect('stud.db')
c = conn.cursor()
c.execute('INSERT INTO data (fname, sname) VALUES (?,?)', (firstname_entry, secondnamename_entry))
conn.commit()
print("OK")
u_ent_btn = Button(text="Enter",command=savedata())
u_ent_btn.pack()
main_menu.mainloop()
打印
#include <iostream>
#include <iomanip>
//#include <boost/fusion/adapted.hpp>
//#include <boost/fusion/include/io.hpp>
#include <boost/spirit/home/x3.hpp>
#include <boost/spirit/home/x3/support/ast/variant.hpp>
namespace x3 = boost::spirit::x3;
namespace ns { namespace ast {
// forward definition
struct uintObj;
//struct varVec;
// define type
using uintPair_t = std::pair<unsigned int, unsigned int>;
using uintVec_t = std::vector<uintObj>;
// general token value:
struct uintObj : x3::variant<unsigned int, uintPair_t> {
using base_type::base_type;
using base_type::operator=;
friend std::ostream& operator<<(std::ostream& os, uintObj const& This) {
struct {
std::ostream& os;
void operator()(unsigned int v) const { os << v; }
void operator()(uintPair_t v) const { os << v.first << "-" << v.second; }
} vis { os };
boost::apply_visitor(vis, This);
return os;
}
};
using varVec = uintVec_t;
} }
namespace ns { namespace parser {
using namespace boost::spirit::x3;
template <typename T> auto as = [](auto p) { return rule<struct _, T> {} = p; };
auto const uintPair = as<ast::uintPair_t> ( uint_ >> '-' >> uint_ );
auto const uintObj = as<ast::uintObj> ( uintPair | uint_ );
auto const varVec = as<ast::varVec> ( '[' >> uintObj % ',' >> ']' );
} }
int main() {
using namespace ns;
std::string const input("[1, 11, 3, 6-4]\n");
auto begin = input.begin(), end = input.end();
ast::varVec result; // ast tree
bool success = phrase_parse(begin, end, parser::varVec, x3::ascii::space, result);
if (success) {
std::cout << "good\n";
for (auto& r : result)
std::cout << r << "\n";
}
else
std::cout << "bad\n";
if (begin != end)
std::cout << "Remaining unparsed: " << std::quoted(std::string(begin, end)) << std::endl;
}