DSL(领域特定语言) for erlang, 适用于erlang的脚本语言。
主要使用erlang的leex和yecc模块进行词法、语法分析,再转换成对应的erlang语言。
- 支持编译执行
- 消除进程堵塞
- 支持顺序、判断、循环等程序逻辑
- 支持变量
- 支持变参
- 支持脚本函数与实现模块自动映射
script: 示例脚本以及生成的代码
src: 源代码
xscript_scanner.xrl: 词法分析文件
xscript_parser.yrl: 语法分析文件<br/
xscript_function_define.erl: 脚本函数实现模块
xscript_utility.erl:公共模块
xscript_file.erl: 文件操作模块
xscript_compile.erl: 脚本语言生成模块
- 如果修改了xscript_scanner.xrl文件,可以使用leex:file("src/xscript_scanner.xrl").重新生成对应的xscript_scanner.erl文件
- 如果修改了xscript_parser.yrl文件,可以使用yecc:file("src/xscript_parser.yrl").重新生成对应的xscript_parser.erl文件,为了正确生成对应的erlang代码,可能需要同步修改xscript_compile.erl文件中对应的生成规则。
xscript_compile:generate_file(ScriptFilename, Options):
ScriptFilename: 脚本文件名(包含相对于工作目录的相对路径)
Options: 选项,当前支持: {out_dir, Dir}: 指定文件生成目录
xscript_compile : 宏FUNCTION_DEFINE定义了当前脚本映射函数的实现模块
//example1:
create_monster();
create_monster(1,500);
create_monster(2,400);
//example2:
if(level() > 3)
{
apply(1,skill,1204);
find_target(300,222,12);
}
else
{
apply(2,skill,1205);
find_target(enemy_scope(1,0,0,0,1000,1000));
}
//example3:
while(random_find(1,num) > 0)
{
attack_target(100);
create_monster(1,500);
}
ErlScriptOutputModule:script_execute(ScriptId).
尾函数(tail function): 如果一个函数在段落语句中是最后一个执行的函数,后面没有其他函数逻辑的函数。
- 如果程序段落中存在阻塞操作,则阻塞操作可以通过异步调用尾函数的方式消除阻塞。
- 将if子句转换为尾函数: if子句后的段落提取成if各条件分支的尾函数,则if子句变成整个段落的尾函数。
- while子句本身看作一个尾函数, 那么while后的所有段落需要提取成一个尾函数作为while函数的尾函数
- 将wait子句转换为尾函数: 将wait子句后的段落提取成一个尾函数,wait通过异步调用的方法调用该尾函数
上面的说明比较绕,一句话说明是:
if/while/wait 子句转换成函数,并且成为程序的尾函数,所有函数递归包含尾函数,在执行完自己的函数后,调用尾函数即可。
编译原理对应的是关键字是:statements statement functions.....
语法分析参考对应的语法分析文件,核心是:
%%段落分析 statements -> '$empty' : []. statements -> metascript '.' statements : [{metascript,'$1'} |'$3']. %%脚本参数定义 statements -> wait_function ';' statements : [{wait_function, '$1', '$3'}]. %%异步等待子句 statements -> if_statement statements : [{if_statement, '$1', '$2'}]. %%IF子句 statements -> while_statement statements : [{while_statement, '$1', '$2'}]. %%WHILE子句 statements -> statement ';' statements : [{statement, '$1'} | '$3']. %%普通子句
[Planned] 支持本地函数定义
[Planned] 扩展使用脚本虚拟机的方法清除阻塞
[Planned] 扩展支持for函数
[Planned] 扩展支持命名空间