路径验证的精神语法

Spirit Grammar For Path Verificiation

本文关键字:语法 验证 路径      更新时间:2023-10-16

我正在尝试使用boost spirit编写一个简单的语法,以验证字符串是否是有效的目录。我使用这些教程,因为这是我尝试的第一个语法:http://www.boost.org/doc/libs/1_36_0/libs/spirit/doc/html/spirit/qi_and_karma.htmlhttp://www.boost.org/doc/libs/1_48_0/libs/spirit/doc/html/spirit/qi/reference/directive/lexeme.htmlhttp://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_可能会消耗所有字符?那么,我如何才能知道某个字符序列是否都以/结尾呢?

从本质上讲,我写上面代码的想法是,我想要从开始的目录。和/有效,然后最后一个字符必须是a/。有人能帮我学习语法吗?或者给我举一个与我想做的更相似的例子?这纯粹是学习如何使用精神的一项附加任务。

编辑所以我用匹配了解析器

bool match = phrase_parse(valid1.begin(), valid1.end(), lexeme[
    ((char_('.') | char_('/')) >> *(+char_ >> char_('/'))],
    ascii::space);
if (match)
{
    std::cout << "Match!" << std::endl;
} 

不确定这是否合适?或者,如果由于其他原因匹配。。。这里还应该使用ascii::空格吗?我在一个教程中读到,这是为了使空间不可知,即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;
  }
}

如果不想忽略空间差异(不应该忽略),请使用parse而不是phrase_parselexeme的使用再次抑制了船长(所以你只是在剥离领先/落后的空间)。另请参阅stackoverflow.com/questions/17072987/boost spirit captain issues/17073965#17073965

使用char_("ab")而不是char_('a')|char_('b')

*char_匹配所有。你可能是指*~char_('/')

我建议使用

 bool ok = qi::parse(b, f, &(lit("./")|'/') >> (*~char_('/') % '/'));

这不会公开匹配的输入。在其周围添加raw[]以实现这一点。

添加> qi::eoi以断言所有输入都已消耗。