我正在从事一个项目,我需要将Netlogo转换为另一种编程语言。我正在使用Boost Spirit,并且已经实施了一些将简单代码语法存储到AST的项目语法。
我面临的问题是,现在我无法确定标识符是变量名称还是函数名称。另外,我不知道特定函数呼叫是否需要一个,两个或多个参数,所以我不知道何时停止寻找更多参数。
例如,函数调用看起来像
id1 id2 id3 id4
可能是:
-
id3
是一个具有id4
作为参数的函数(假设其返回值是id5
(,而id1
是一个具有id2
和id5
作为参数
的函数
但也可能是:
-
id1
具有id2
id3
id4
作为参数(除id1
以外的所有均为变量名称(
我已经考虑过每次声明变量或函数时都使用符号并添加新项目,这将有助于区分变量名称和函数名称,但是...
- 我应该/应该如何存储函数使用Boost Spirit需要的参数数量?也许在解析函数定义时使用另一个带有语义动作的符号表?
- 一旦我知道如何获得所需的参数,一旦我在解析表达式时找到函数标识符,我该如何获得该值?
- 这是使用符号将变量名称与函数名称区分开的好解决方案?
最后我所做的是以下内容:
- 使用函数名称作为密钥创建一个符号表,以及作为存储数据的参数数量。
qi::symbols<char, int> f_args;
- 在功能解析器上使用语义动作获取功能名称和参数列表,然后将其发送到外部函数以将数据存储在符号表上。
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) ];
- 当在函数定义之外找到函数名称(含义是函数调用(时,我将存储在符号表上的数据加载到重复指令上,并期望函数需要的确切参数数量。<<<<<<<</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 | '_' | '-')]];
唯一答案的问题是最后一个问题。希望在这个领域有更多经验的人会解释它。