是否可以使用 boost::spirit QI 强制执行函数参数类型

问题描述 投票:0回答:1

我正在编写解析器来解析内置函数列表。例如:

Function1(int p1, string p2)

Function2(string p1, int p2, string p3)

Function3(string p1, string p2, int p3, int p4, string p5)
等等

我在编写规则来单独解析这些函数时没有任何问题,例如为每个函数创建 AST 结构,然后编写规则来解析它们,如下所示的 Function1 规则:

func1_ = lit("Function1") >> '(' >> int_ >> ',' >> literal_ >> ')';

但是这个函数列表很长,所以我会遇到允许变体的限制。我正在考虑创建一个 AST 结构来解析所有这些结构,如下所示:

struct FunctionTemplate {
  std::string name;
  std::vector<boost::variant<int, std::string>> params
};

为了简单起见,我仅使用 intstring 作为参数的类型。

对于规则,我可以这样做:

params_ = int_ | literal_;
func_tpl_ = 
  (raw["Function1"] >> '(' >> (params_ % ',') >> ')')
  | (raw["Function2"] >> '(' >> (params_ % ',') >> ')')
  ; 

它解析得很好,但这个规则也将允许错误的参数数据类型顺序,对于 Function1,它也会接受 string 然后 int 而不是相反。这也将接受更多的参数。

那么是否可以强制执行参数的数据类型顺序参数数量,以便它不仅可以正确解析,而且可以匹配正确的顺序和正确的参数数量?

谢谢

c++ boost boost-spirit
1个回答
0
投票

但是这个函数列表很长,所以我会遇到允许变体的限制。我正在考虑创建一个 AST 结构来解析所有这些结构,如下所示

您可以按照您的意愿编写语法产生式,只需将参数解析为通用数据类型(例如

numbers instead of 
int_
directly, with number as a
rule`。这样您就可以解析为通用(非变体)数据类型,同时仍然遵循不同名称的不同产生方式。

事实上,为了可扩展性/可维护性,您可以在此处使用 Nabialek 技巧,并将各个函数存储在相同声明属性的单独规则中。我必须在这个网站上提供一些示例,这些示例可能会向您展示一些具有非常相似方法的类似脚本的语法。

© www.soinside.com 2019 - 2024. All rights reserved.