解析不带参数分隔符的函数参数

时间:2019-05-21 08:47:59

标签: compiler-construction boost-spirit

我正在一个项目中,我需要将NetLogo转换为另一种编程语言。我正在使用Boost Spirit,并且已经实现了一些将简单代码语法存储到AST中的项目语法。

我面临的问题是,现在我不知道标识符是变量名还是函数名。另外,我不知道特定的函数调用是否需要一个,两个或多个参数,所以我不知道何时停止寻找更多的参数。

例如,函数调用看起来像

id1 id2 id3 id4

可能是:

  • id3是一个以id4作为参数的函数(假设其返回值为id5),而id1是一个具有{{1 }}和id2作为参数

但是也可能是:

  • id5id1 id2 id3作为参数(id4以外的都是变量名)

我已经考虑过使用符号并在每次声明变量或函数时添加新项,这将有助于区分变量名和函数名,但是...

  • 如何/应该使用Boost Spirit存储函数需要的参数数量?也许在解析函数定义时使用另一个带有语义动作的符号表?
  • 一旦我知道如何获取所需的参数数量,一旦在解析表达式时找到函数标识符,如何获得该值?
  • 使用符号区分变量名和函数名是一个很好的解决方案吗?

1 个答案:

答案 0 :(得分:0)

最后我要做的是以下事情:

  • 使用函数名称作为键,并以参数数作为数据存储来创建Symbols表。
qi::symbols<char, int> f_args;
  • 在函数解析器上使用语义动作来获取函数名称和参数列表,并将其发送到外部函数以将数据存储在Symbols表中。
void store_function (std::string name, std::list<std::string> args) {
    f_args.add(name, args.size());
    std::cout << name << " " <<  args.size() << std::endl;
}
function_ = (
        lexeme[(string("to-report") | string("to")) >> !(alnum | '_')]  // make sure we have whole words
   >   identifier 
   >   ('[' > argument_list > ']')
   >   body
   >   lexeme[string("end") >> !(alnum | '_')]
) [ phx::bind(&store_function, _2, _3) ];
  • 当在函数定义(即函数调用)之外找到函数名称时,我加载存储在Symbols Table中的数据以在重复指令上使用它,并期望函数需要的确切参数数目。 / li>
function_call = 
    function_name >> 
    repeat( phx::ref(n_args) )[identifier];

function_name = 
    !lexeme[keywords >> !(alnum | '_')] >> 
    &lexeme[f_args [phx::ref(n_args) = _1] >> !(alnum | '_')] >> 
    raw[lexeme[(alpha | '_') >> *(alnum | '_' | '-')]];

此答案唯一无法回答的问题是最后一个。希望有更多在该领域有经验的人会对此进行解释。