Skip to content

DSL(领域特定语言) for erlang, 适用于erlang的脚本语言。

Notifications You must be signed in to change notification settings

sysuzhang/ErlScript

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

52 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ErlScript

DSL(领域特定语言) for erlang, 适用于erlang的脚本语言。
主要使用erlang的leex和yecc模块进行词法、语法分析,再转换成对应的erlang语言。

特性说明

  1. 支持编译执行
  2. 消除进程堵塞
  3. 支持顺序、判断、循环等程序逻辑
  4. 支持变量
  5. 支持变参
  6. 支持脚本函数与实现模块自动映射

目录说明

script: 示例脚本以及生成的代码
src: 源代码

文件说明

xscript_scanner.xrl: 词法分析文件
xscript_parser.yrl: 语法分析文件<br/ xscript_function_define.erl: 脚本函数实现模块
xscript_utility.erl:公共模块
xscript_file.erl: 文件操作模块
xscript_compile.erl: 脚本语言生成模块

注意:

  1. 如果修改了xscript_scanner.xrl文件,可以使用leex:file("src/xscript_scanner.xrl").重新生成对应的xscript_scanner.erl文件
  2. 如果修改了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定义了当前脚本映射函数的实现模块

示例example(对应的生成文件,见script目录):

    //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);
    }

调用API:

ErlScriptOutputModule:script_execute(ScriptId).

扩展

尾函数(tail function): 如果一个函数在段落语句中是最后一个执行的函数,后面没有其他函数逻辑的函数。

结论:

  1. 如果程序段落中存在阻塞操作,则阻塞操作可以通过异步调用尾函数的方式消除阻塞。

同步阻塞代码清除方法:

  1. 将if子句转换为尾函数: if子句后的段落提取成if各条件分支的尾函数,则if子句变成整个段落的尾函数。
  2. while子句本身看作一个尾函数, 那么while后的所有段落需要提取成一个尾函数作为while函数的尾函数
  3. 将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'].         %%普通子句

TODO:

[Planned] 支持本地函数定义
[Planned] 扩展使用脚本虚拟机的方法清除阻塞
[Planned] 扩展支持for函数
[Planned] 扩展支持命名空间

About

DSL(领域特定语言) for erlang, 适用于erlang的脚本语言。

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published