首页 > 解决方案 > 如何将 PEGTL 解析器与单独的词法分析器一起使用?

问题描述

我已经有一个词法分析器,并且想使用我自己的标记类型作为 PEGTL 解析器的输入。例如,这里是 sum 示例的修改版本,它从标准输入读取:

#include <cstdlib>
#include <iostream>
#include <sstream>
#include <string>

#include <tao/pegtl.hpp>

using namespace TAO_PEGTL_NAMESPACE;

namespace sum
{
   struct num : seq< plus< digit > > {};

   struct int_list
      : list< num, one< ',' > >
   {};

   struct grammar
      : seq< int_list, eof >
   {};

   template< typename Rule >
   struct action
   {};

   template<>
   struct action< num >
   {
      template< typename ActionInput >
      static void apply( const ActionInput& in, int& sum )
      {
         sum += atoi(in.string().c_str());
      }
   };

}  // namespace sum

struct Token {
   typedef enum { COMMA, NUM, END_OF_FILE } Type;
   Token(Type type, int num = 0) : type(type), num(num) {}
   Type type;
   int num;
};

int main()
{
   // this works, can be called like this:
   // echo -n "1,2,3" | ./a.out
   int d = 0.0;
   if( parse< sum::grammar, sum::action >( istream_input(std::cin, 16, "stdin"), d )) {
      std::cout << "parsing OK; sum = " << d << std::endl;
   }
   else {
      std::cout << "parsing failed" << std::endl;
   }

   // how can I do this when I have already the tokens in a vector?
   std::vector<Token> tokens;
   tokens.push_back(Token(Token::Type::NUM, 1));
   tokens.push_back(Token(Token::Type::COMMA));
   tokens.push_back(Token(Token::Type::NUM, 2));
   tokens.push_back(Token(Token::Type::COMMA));
   tokens.push_back(Token(Token::Type::NUM, 3));
   tokens.push_back(Token(Token::Type::END_OF_FILE));
}

可以这样编译:g++ -std=c++17 -I PEGTL/include parser.cc. PEGTL/include 中的文件来自PEGTL 存储库

我如何需要修改解析器以便使用标记向量而不是std::cin?我想我必须编写自己的 ParseInput 结构,但我无法为它定义所有必需的方法和类型。对于这个 sum 示例,我如何在解析器中使用令牌对象?

标签: c++

解决方案


推荐阅读