路径验证的精神语法
Spirit Grammar For Path Verificiation
我正在尝试使用 boost spirit 编写一个简单的语法来验证字符串是否为有效目录。我正在使用这些教程,因为这是我尝试的第一个语法:
http://www.boost.org/doc/libs/1_36_0/libs/spirit/doc/html/spirit/qi_and_karma.html
http://www.boost.org/doc/libs/1_48_0/libs/spirit/doc/html/spirit/qi/reference/directive/lexeme.html
http://www.boost.org/doc/libs/1_44_0/libs/spirit/doc/html/spirit/qi/tutorials/employee___parsing_into_structs.html
目前我想到的是:
// I want these to be valid matches
std::string valid1 = "./";
// This string could be any number of sub dirs i.e. /home/user/test/ is valid
std::string valid2 = "/home/user/";
using namespace boost::spirit::qi;
bool match = phrase_parse(valid1.begin(), valid1.end(), lexeme[
((char_('.') | char_('/')) >> +char_ >> char_('/')],
ascii::space);
if (match)
{
std::cout << "Match!" << std::endl;
}
然而,这不匹配。关于原因,我有一些想法;然而,在做了一些研究之后,我还没有找到答案。例如,我假设 +char_ 可能会消耗所有字符?那么我怎样才能知道一些字符序列是否都以 / 结尾?
基本上我编写上述代码的想法是我希望目录以 .和 / 有效,最后一个字符必须是 /。有人可以帮助我学习语法或指出与我想做的事情更相似的例子吗?这纯粹是学习如何使用精神的一种锻炼。
编辑
所以我有解析器来匹配使用:
bool match = phrase_parse(valid1.begin(), valid1.end(), lexeme[
((char_('.') | char_('/')) >> *(+char_ >> char_('/'))],
ascii::space);
if (match)
{
std::cout << "Match!" << std::endl;
}
不确定这是否正确?或者,如果它由于其他原因匹配...还应该在此处使用 ascii::space 吗?我在一个教程中读到它是为了使空间不可知,即 a b 等同于 ab。我不想在路径名中使用哪个?如果这不是正确的使用方式,那会是什么?
SSCCE:
#include <string>
#include <iostream>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/qi_char.hpp>
#include <boost/spirit/include/qi_eoi.hpp>
int main()
{
namespace qi = boost::spirit::qi;
std::string valid1 = "./";
std::string valid2 = "/home/blah/";
bool match = qi::parse(valid2.begin(), valid2.end(), &((qi::lit("./")|'/') >> (+~qi::char_('/') % '/') >> qi::eoi));
if (match)
{
std::cout << "Match" << std::endl;
}
}
如果您不想忽略 space 差异(您不应该这样做),请使用 parse
而不是 phrase_parse
。使用 lexeme
再次抑制船长(所以你只是剥离 leading/trailing space)。另请参阅计算器。com/questions/17072987/boost-spirit-skipper-issues/17073965#17073965
使用 char_("ab")
而不是 char_('a')|char_('b')
。
*char_
匹配 一切。您的意思可能是 *~char_('/')
.
我建议像
bool ok = qi::parse(b, f, &(lit("./")|'/') >> (*~char_('/') % '/'));
这不会公开匹配的输入。在其周围添加 raw[]
以实现 .
添加 > qi::eoi
断言所有输入都已消耗。
我正在尝试使用 boost spirit 编写一个简单的语法来验证字符串是否为有效目录。我正在使用这些教程,因为这是我尝试的第一个语法: http://www.boost.org/doc/libs/1_36_0/libs/spirit/doc/html/spirit/qi_and_karma.html http://www.boost.org/doc/libs/1_48_0/libs/spirit/doc/html/spirit/qi/reference/directive/lexeme.html http://www.boost.org/doc/libs/1_44_0/libs/spirit/doc/html/spirit/qi/tutorials/employee___parsing_into_structs.html
目前我想到的是:
// I want these to be valid matches
std::string valid1 = "./";
// This string could be any number of sub dirs i.e. /home/user/test/ is valid
std::string valid2 = "/home/user/";
using namespace boost::spirit::qi;
bool match = phrase_parse(valid1.begin(), valid1.end(), lexeme[
((char_('.') | char_('/')) >> +char_ >> char_('/')],
ascii::space);
if (match)
{
std::cout << "Match!" << std::endl;
}
然而,这不匹配。关于原因,我有一些想法;然而,在做了一些研究之后,我还没有找到答案。例如,我假设 +char_ 可能会消耗所有字符?那么我怎样才能知道一些字符序列是否都以 / 结尾?
基本上我编写上述代码的想法是我希望目录以 .和 / 有效,最后一个字符必须是 /。有人可以帮助我学习语法或指出与我想做的事情更相似的例子吗?这纯粹是学习如何使用精神的一种锻炼。
编辑 所以我有解析器来匹配使用:
bool match = phrase_parse(valid1.begin(), valid1.end(), lexeme[
((char_('.') | char_('/')) >> *(+char_ >> char_('/'))],
ascii::space);
if (match)
{
std::cout << "Match!" << std::endl;
}
不确定这是否正确?或者,如果它由于其他原因匹配...还应该在此处使用 ascii::space 吗?我在一个教程中读到它是为了使空间不可知,即 a b 等同于 ab。我不想在路径名中使用哪个?如果这不是正确的使用方式,那会是什么?
SSCCE:
#include <string>
#include <iostream>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/qi_char.hpp>
#include <boost/spirit/include/qi_eoi.hpp>
int main()
{
namespace qi = boost::spirit::qi;
std::string valid1 = "./";
std::string valid2 = "/home/blah/";
bool match = qi::parse(valid2.begin(), valid2.end(), &((qi::lit("./")|'/') >> (+~qi::char_('/') % '/') >> qi::eoi));
if (match)
{
std::cout << "Match" << std::endl;
}
}
如果您不想忽略 space 差异(您不应该这样做),请使用 parse
而不是 phrase_parse
。使用 lexeme
再次抑制船长(所以你只是剥离 leading/trailing space)。另请参阅计算器。com/questions/17072987/boost-spirit-skipper-issues/17073965#17073965
使用 char_("ab")
而不是 char_('a')|char_('b')
。
*char_
匹配 一切。您的意思可能是 *~char_('/')
.
我建议像
bool ok = qi::parse(b, f, &(lit("./")|'/') >> (*~char_('/') % '/'));
这不会公开匹配的输入。在其周围添加 raw[]
以实现 .
添加 > qi::eoi
断言所有输入都已消耗。