[背景]

平时喜欢写游戏脚本,经常用按键精灵,在物理机上用还是很方便好用的,但有时多开挂机,游戏又有驱动保护时,就得在虚拟机里面挂。这时按键的资源占用大问题就很突出。在VM里面运行按键经常是超慢镜头,用他强大的脚本编辑器修改脚本时更是一场噩梦。所以萌生了自己写个功能简单的脚本解释器的想法。在写这个解释器的时候有点小经验,在这和大家分享(或者说共同研究研究)。

事先声明,由于我写程序水平极低,所以解释器只有极少极简单的功能。另外下面只写思路不贴代码。

[正文]

首先是脚本语句怎么区分问题。我比较喜欢C语言的分号结尾,这种表示方式很容易从整个脚本里面拆分出一个个语句。

接下来就是怎么表示一个语句。这里我的做法比较简陋,以一个命令开头,比如

“press",

后面跟上用逗号作间隔的一串参数。于是脚本可以写成形如这样的一段字符串:

press,A,2;click,100,100,2;

(意思是按下A键2次,鼠标双击100,100那个点)

处理这样的脚本很简单,执行时先从第一个字母开始复制,直到遇到“;”停止,

那样就取出一条语句。再加个循环就实现逐句读出。

读出一句后,又从第一个字母开始复制到逗号结束,就可以取出第一个命令。

后面的各参数也是这样处理,把一个语句划分成几个字符串变量。

接着用strcmp来比较第1个字符串变量,假设它是"press“那么就执行sendmessage函数,

把后面几个字符串用类型转换函数转成参数,那样就实现了形如press,a,2;这样一条语句。

但是语句种类一多就会形成一个很大的像下面这样的语句段:

if(!strcmp(str1,"press")){};

else if(!strcmp(str1,"click")){};

else ....

占地方不说,这么多重的strcmp,执行效率会很低。

所以可以先 switch(strlen(str1))

这样根据命令长度预分类一下,再用if结构做2次分类,减少比较次数。

当然switch(str1[0])

以命令的首字母来分类也是一种不错的方法。

那么执行代码应该放在哪?直接放到如onok这样的函数是不行的。因为这些代码的执行都在毫秒级,一下子就执行完。

如果加个while更麻烦,他会吸干CPU的运算能力,电脑像死机一样。

所以,应该把这样的执行函数放到Timer里面去,设置一个全局的指针,指向当前执行到哪条语句,

每次Timer事件发生时执行1条语句,接着指针向下个分号移去。

delay? 用Timer有个比较难处理的命令,就是delay(延时)命令。比如想执行到某行就停下来等10秒,于是写了个delay,10;

这样的语句不能用sleep(10000);来处理,不然执行到时会引起电脑反应迟顿。

我的方法是设置一个全局变量

tDelay =

GetTickCount()+延迟时间 ; 然后Timer里面:

GetTickCount()>tDelay ?

指向下一个命令:什么也不做;

//哈哈!发现用这条C语句表达,可以少打很多字。

补充说下,使用timer还要注意保证onTimer程序段执行时的原子性,所以通常写法是

case(nID):

if(timing==0){

timing =1; //加个锁

.......  ;

timing =0; //解锁

}

break;

到这里简单语句已经没问题了,接着是流程控制方面的语句,如if

... else ... endif  或者 while

... wend

(因为我水平有限,没想到怎么处理变量,所以没有for

这样的语句)

先说while比较简单。这个很容易,执行到while先把当前语句位置存入stack[++pos]数组里面

(提醒,别看漏了pos前面的++哦),记下当前执行到哪行语句。

然后判断一下后面的条件,符合就执行下条命令,不符合就pos--;然后向下查找wend;执行wend后面的命令。

如果符合,并执行到wend时处理也很简单,把命令指针指向stack[pos--](注意减减)就回到了while那里继续判断。

而且这样处理后,while的嵌套也不成问题了。但是(恩,最怕就是看到但是)如果wihe...wend段很长,

每次查找wend还是很花时间的。为了快速跳转,可以在脚本执行前做个小的预处理,先查好每个while对应的wend的位置,

存进一个数组jumptable[maxline]中,以命令所在行数为下标,下次执行到while或者wend就可以直接跳到jumptable[currentline]。

if 和 else

也可以存进相同的跳转表内,加快跳转速度。但要注意的是if

要记下两个位置:else和endif 。

而else 只要记住1个位置endif

。是的else也要记,接着看就知道为什么了。

如果条件成立,先stack[++pos]=1,然后执行下一条命令。

如果条件不成立,stack[++pos]=0,然后跳到else命令。

执行到else判断下

stack[pos]==1 ? 跳转到endif

:执行下一条命令;

执行到endif时只要简单的pos--;

这样同样也处理了嵌套if的问题。

没看懂 ? 慢慢想下 : 接着看下面

循环结构OK了,变量不会弄,咱只好研究下子程序了。

有了上面while和if的基础,子程序也很容易。在脚本预处理时设置一个字符串表,记下子程序名和语句开始位置。

假设子程序用 sub,子程序1;  .........

return;这样的结构。

调用时 call,子程序1;

先把当前命令的下一条命令指针位置存入stack[++pos]里面,备作返回时使用。

然后查子程序名字表,查到“子程序1”时,跳到相应位置执行。

执行完了,遇到return时,跳回stack[pos--]处执行。

以上是自己在写那个简陋的脚本解释器时总结的一点心得。

由于水平太低,变量处理,数值计算一直没想到好办法,如果你有思路或者相关资料,请不吝赐教!

如何使用c语言写脚本解释器,脚本解释器编写思路相关推荐

  1. mapreduce编程实例python-使用Python语言写Hadoop MapReduce程序

    原标题:使用Python语言写Hadoop MapReduce程序 Python部落(python.freelycode.com)组织翻译,禁止转载,欢迎转发. 在本教程中,我将描述如何使用Pytho ...

  2. python自动化测试脚本怎么写_自动化测试脚本一般用什么语言写

    1. 自动化测试脚本一般用什么语言写 我主要是做web测试的,最近也在研究自动化测试. 自动化测试主流的工具应该是QTP吧,这个你可以去51testing论坛搜到很多相关的资料.QTP是一个商业软件. ...

  3. 写游戏自动化脚本用哪个语言好

    写游戏自动化脚本可以使用多种语言,具体选择哪种语言取决于您的需求和技能. 一些常用的语言包括 Python, JavaScript, Ruby 和 C#. 如果您对编程经验较少,可以考虑使用 Pyth ...

  4. 在Linux中如何运行C语言写的脚本

    目录 1:Linux下如何运行C语言脚本 2:实例展示 1:Linux下如何运行C语言脚本 Linux别的系统我不知道是不是这个方法,我是用的ubuntu的,其他的我也没测试过,但是ubuntu应该是 ...

  5. 把C++当脚本语言写

    把C++当脚本语言写! 提到脚本,脑海里马上闪过一大堆:Python,Perl,Ruby,PHP,JS,VBS,LUA... 不过你有没听说过,用经典的C++做脚本语言吗?先不多说,上个图.(先别纠结 ...

  6. 用c写按键精灵脚本语言,按键精灵之插件编写

    按键精灵最大的优点就是简单直接,本身没有复杂的结构,很容易理解,但是要想作出强大的脚本,需要的就是插件.插件的编写通常使用高级语言,如vc,delphi,vb等等,通过这些语言编写出功能强大的模块,在 ...

  7. php写一个shell脚本文件格式,一篇文章学会——shell脚本编写

    用了caffe有一段时间了,感觉自己写shell脚本的能力有待提高,特地从菜鸟笔记处系统的看了一遍,其实学习基础就可,内容也不多,我就不总结了.把网站上的内容用markdown重新编辑了一下,各位可以 ...

  8. linux gdb 脚本,如何写gdb命令脚本

    作为UNIX/Linux下使用广泛的调试器,gdb不仅提供了丰富的命令,还引入了对脚本的支持:一种是对已存在的脚本语言支持,比如python,用户可以直接书写python脚本,由gdb调用python ...

  9. 菜鸟初识脚本 and 脚本语言

    让我们先来查一下script的中文意思 script中文之意 script [skript] n.脚本:手迹:书写用的字母 vt.把-改编为剧本 vi. 写电影脚本 _________________ ...

  10. 如何写SHELL脚本?尝试自己编写一个简单脚本

    背景 现在多数的服务器都是Linux系统的,需要通过shell来进行操作,而利用shell脚本,可以大大提高开发维护的效率. 知识剖析 什么是shell shell是一个命令行解释器,它为用户提供了一 ...

最新文章

  1. 微信支付:“当前页面的URL未注册”
  2. mysql 同步备份数据库
  3. 去除有序数组/链表的重复元素--双指针原地修改
  4. matlab应用大全二手,MATLAB应用大全(附光盘)-JobPlus
  5. BlazorCharts 原生图表库的建设历程
  6. 【图论】【Floyed】舞会邀请(CODE[VS] 2604)
  7. 通信中的频谱效率与能量效率
  8. mysql查询流程解析及重要知识总结
  9. 苹果将于 2025 年推出的 Apple Car 长什么样?
  10. Tomcat的三个端口
  11. 计蒜客---N的-2进制表示
  12. 简单使用Spring Boot+JpaRepository+hibernate搭建项目
  13. Keycloak服务器安装和配置
  14. 微信emoji表情数据如何添加到json中
  15. android 手机上设置呼叫转移
  16. Navicat远程连接服务器mysql,先后报错10060,10061
  17. 响应式H5图片网盘外链系统源码 自适应PC手机端
  18. c 连接oracle otl,C++类库:OTL通用的数据库连接类库
  19. Azido-TAT,大环化合物,双功能螯合剂的性质
  20. k8s的namespace资源一直terminating问题解决

热门文章

  1. VGA/DVI/HDMI/DP/Type-C等常用显示接口对比介绍
  2. 手把手教你如何把笔记本变触屏,就是那么容易!
  3. 批量扫描工具btscan
  4. 美家市场教育频道改版上线,倾心推荐大屏精品课程
  5. 操作系统-进程方案知识详解
  6. 为什么很多人炒芹菜都要把叶子摘掉
  7. NR polar Code 三 极化内核(克罗克内积)
  8. Flask - 相册
  9. 【外宣】实事为民:“5G+智慧长江”助推长江管理数智化
  10. 2017年,个人网站/个人博客的价值与意义