Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Compiler construction 解析没有参数分隔符的函数参数_Compiler Construction_Boost Spirit - Fatal编程技术网

Compiler construction 解析没有参数分隔符的函数参数

Compiler construction 解析没有参数分隔符的函数参数,compiler-construction,boost-spirit,Compiler Construction,Boost Spirit,我正在做一个项目,我需要将NetLogo翻译成另一种编程语言。我正在使用BoostSpirit,并且已经实现了一些将简单代码语法存储到AST中的项目语法 我面临的问题是,现在我无法判断标识符是变量名还是函数名。此外,我不知道特定的函数调用是否需要一个、两个或多个参数,因此我不知道何时停止寻找更多参数 例如,函数调用可以如下所示 id1 id2 id3 id4 这可能是: id3是一个以id4作为参数的函数(假设其返回值为id5),而id1是一个以id2和id5作为参数的函数 但也可能是:

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

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

例如,函数调用可以如下所示

id1 id2 id3 id4
这可能是:

  • id3
    是一个以
    id4
    作为参数的函数(假设其返回值为
    id5
    ),而
    id1
    是一个以
    id2
    id5
    作为参数的函数
但也可能是:

  • id1
    id2
    id3
    id4
    作为参数(除
    id1
    外,所有变量都是变量名)
我曾经考虑过在每次声明变量或函数时使用符号并添加新项,这将有助于区分变量名和函数名,但是

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

最后,我做了以下几点:

  • 创建了一个符号表,使用函数名作为键,参数数作为存储的数据
qi::符号f_参数;
  • 在函数解析器上使用语义操作来获取函数名和参数列表,并将其发送到外部函数以将数据存储在符号表中
void store_函数(std::string name,std::list args){
f_args.add(名称,args.size());
std::cout('['>参数列表>']'))
>身体
>词素[string(“end”)>>!(alnum |')]
)[phx::bind(&store_函数,_2,_3)];
  • 当在函数定义(即函数调用)之外找到函数名时,我加载存储在Symbols表中的数据,将其用于repeat指令,并期望函数需要的参数的确切数量
函数调用=
功能名称>>
重复(phx::ref(n_参数))[identifier];
函数名称=
!lexeme[关键词>>!(alnum |''.'''.')]>>
&词素[f|u args[phx::ref(n|u args)=_1]>>!(alnum |'|')]>>
原始[词素[(alpha |'|')>*(alnum |'|'|'-')];

这个答案没有回答的唯一一个问题是最后一个问题。希望在这个领域有更多经验的人能解释它。

看看编译器是如何将源代码编译成machinecode的可能会有所帮助。下面是c编译器所做工作的一个非常基本的概述:1)语法分析。将代码拆分为标记,例如。“int void();”->“int”、“void”、“(“,”)、“;”第二)检查此语法是否正确。例如,“int void(;”将不正确第三)在语义分析中将函数或变量的每个声明写入具有类型信息的符号表(这就是问题所在)检查程序的语义是否正确。例如,int test=std::string{“test”};如果我没有错的话,第1步和第2步是由Spirit语法处理的。然后,第3步是我要问的两个问题之一,所以我想找符号表是最好的方法?第4步是我不知道如何处理的步骤(至少是函数参数部分)重新思考你所说的,我想我的问题不是在第四步而是在第二步。我不知道如何解析函数调用,因为我没有任何令牌划界,在那里参数开始,并且为什么问题被标记为C++,甚至提升。精神。这两者都没有。因为我正在使用Boost精神来开发解析。r、 我正在寻找一些关于如何处理这一问题的建议,当然也包括那些图书馆。我将更新我的问题,以更好地反映这一点。