这是第四篇了,之所以隔了这么久才写,一方面是因为最近开始实习了,另一方面是因为设计语法真是要考虑很多东西。

于是我去读了这本书,里面实现了两种语言,一种跟js差不多语法,用ast解释执行;另一种语法类似java,编译成字节码执行。

于是ngscript就愉快的决定使用类似js语法、编译成字节码了。

这之间还看了一本《flex与bison》,主要看了看LALR(1)中冲突的处理和写文法要注意的事情。

现在的BNF已经写成这个样子了。可能还会不断的改。常用的控制结构和try…catch都有。

//starter symbol
%start <program>;
%array <statements> <param_list> <params>;
%equiv <expr> <expr1> <expr2> <expr3> <expr4> <expr5> <expr6> <expr7> <expr8> <nullable_expr>;
%filter semicolon comma; <program> ::= <statements>; //----------------------------------------------------------------------------
//statements is a collection of statement; <statements> ::= NULL;
<statements> ::= <statement> <statements>; //----------------------------------------------------------------------------
//statement forms
%equiv <statement> <flow_statement> <expr_statement> <fc_statement>; <statement> ::= <flow_statement>;
<statement> ::= <expr_statement>;
<statement> ::= <fc_statement>;
<statement> ::= <throw_exception>; <flow_statement> ::= <function_decl>;
<flow_statement> ::= <if_block>;
<flow_statement> ::= <for_block>;
<flow_statement> ::= <if_else_block>;
<flow_statement> ::= <while_block>;
<flow_statement> ::= <try_block>;
<flow_statement> ::= <switch_block>; <expr_statement> ::= <expr> semicolon;
<throw_exception> ::= throw <expr> semicolon => <expr>; <fc_statement> ::= <return_val>;
<fc_statement> ::= <return_void>;
<fc_statement> ::= break semicolon;
<fc_statement> ::= continue semicolon; <return_val> ::= return <expr> semicolon => <expr>;
<return_void> ::= return semicolon; //error handling
//<statement> ::= ERROR semicolon; //----------------------------------------------------------------------------
//details of function declaration <function_decl> ::= function ident lparen <param_list> rparen lcurly <statements> rcurly
=> ident <param_list> <statements>;
<param_list> ::= ident comma <param_list>;
<param_list> ::= ident;
<param_list> ::= NULL;
//----------------------------------------------------------------------------
//details of if block and else <if_block> ::= if lparen <expr> rparen lcurly <statements> rcurly
=> <expr> <statements> ;
<if_else_block> ::= if lparen <expr> rparen lcurly <statements> rcurly else lcurly <statements> rcurly
=> <expr> <statements> <statements>; //----------------------------------------------------------------------------
//details of expr <expr> ::= <expr> assign <expr1> => assign <expr> <expr1>;
<expr> ::= <expr> sub_assign <expr1> => sub_assign <expr> <expr1>;
<expr> ::= <expr1>; <expr1> ::= <expr1> or <expr2> => or <expr1> <expr2>;
<expr1> ::= <expr2>; <expr2> ::= <expr2> and <expr3> => and <expr2> <expr3>;
<expr2> ::= <expr3>; <expr3> ::= <expr3> eq <expr4> => eq <expr3> <expr4>;
<expr3> ::= <expr3> neq <expr4> => neq <expr3> <expr4>;
<expr3> ::= <expr4>; <expr4> ::= <expr4> gt <expr5> => gt <expr4> <expr5>;
<expr4> ::= <expr4> lt <expr5> => lt <expr4> <expr5>;
<expr4> ::= <expr4> ge <expr5> => ge <expr4> <expr5>;
<expr4> ::= <expr4> le <expr5> => le <expr4> <expr5>;
<expr4> ::= <expr5>; <expr5> ::= <expr5> add <expr6> => add <expr5> <expr6>;
<expr5> ::= <expr5> sub <expr6> => sub <expr5> <expr6>;
<expr5> ::= <expr6>; <expr6> ::= <expr6> mul <expr7> => mul <expr6> <expr7>;
<expr6> ::= <expr6> div <expr7> => div <expr6> <expr7>;
<expr6> ::= <expr6> mod <expr7> => mod <expr6> <expr7>;
<expr6> ::= <expr7>; <expr7> ::= not <expr8>;
<expr7> ::= s_minus <expr8>;
<expr7> ::= inc <expr8>;
<expr7> ::= dec <expr8>;
<expr7> ::= typeof <expr8>;
<expr7> ::= new <expr8> lparen <params> rparen => new <expr8> <params>;
<expr7> ::= <expr8>; <expr8> ::= <expr8> dot ident => dot <expr8> ident;
<expr8> ::= lparen <expr> rparen => <expr>;
<expr8> ::= <expr8> lsqr <expr> rsqr => array <expr8> <expr>;
<expr8> ::= <expr8> lparen <params> rparen => funcall <expr8> <params>;
<params> ::= <expr> comma <params>;
<params> ::= <expr> ;
<params> ::= NULL; <expr8> ::= lcurly <params> rcurly;
<expr8> ::= float;
<expr8> ::= ident;
<expr8> ::= integer;
<expr8> ::= string;
<expr8> ::= function lparen <param_list> rparen lcurly <statements> rcurly
=> lambda <param_list> <statements>; <for_block> ::= for lparen <nullable_expr> semicolon <nullable_expr> semicolon <nullable_expr> rparen lcurly <statements> rcurly
=> <nullable_expr> <nullable_expr> <nullable_expr> <statements>; <nullable_expr> ::= <expr>;
<nullable_expr> ::= NULL; <while_block> ::= while lparen <expr> rparen lcurly <statements> rcurly
=> <expr> <statements>; <try_block> ::= try lcurly <hooked_statements> rcurly catch lparen ident rparen
lcurly <hooked_statements> rcurly finally lcurly <statements> rcurly
=> <hooked_statements> ident <hooked_statements> <statements>; %equiv <statements> <hooked_statements>; <hooked_statements> ::= <hooked_statement> <hooked_statements>;
<hooked_statements> ::= NULL; %equiv <statement> <hooked_statement> <hooked_fc_statement>; <hooked_statement> ::= <flow_statement>;
<hooked_statement> ::= <expr_statement>;
<hooked_statement> ::= <hooked_fc_statement>;
<hooked_statement> ::= <throw_exception>; <hooked_fc_statement> ::= <hooked_return_val>;
<hooked_fc_statement> ::= <hooked_return_void>;
<hooked_fc_statement> ::= <hooked_break>;
<hooked_fc_statement> ::= <hooked_continue>; <hooked_return_val> ::= return <expr> semicolon => <expr>;
<hooked_return_void> ::= return semicolon;
<hooked_break> ::= break semicolon;
<hooked_continue> ::= continue semicolon; <switch_block> ::= switch lparen <expr> rparen lcurly <switch_cases> <default_case> rcurly
=> <expr> <switch_cases> <default_case>; <switch_block> ::= switch lparen <expr> rparen lcurly <switch_cases> rcurly
=> <expr> <switch_cases>; %array <switch_cases>; <switch_cases> ::= <switch_case> <switch_cases>;
<switch_cases> ::= NULL; <switch_case> ::= case <expr> colon <statements>
=> <expr> <statements>;
<default_case> ::= default colon <statements>
=> <statements>;

parseroid加上这个描述,就可以分析出ngscript程序的语法树。大概是这个样子

生成树之后就是编译成字节码了,这个会在下一篇中详述。

实现自己的脚本语言ngscript之三:语法设计的更多相关文章

  1. 关于JS脚本语言的基础语法

    JS脚本语言的基础语法:输出语法  alert("警告!");  confirm("确定吗?");   prompt("请输入密码");为弱 ...

  2. Cocos2d-x 脚本语言Lua基本语法

    Cocos2d-x 脚本语言Lua基本语法 前面一篇博客对Lua这门小巧的语言进行了简单的介绍.本篇博客来给大家略微讲一下Lua的语法.不会长篇累牍得把Lua的全部语法都讲一遍,这里通过下面几点来讲L ...

  3. 实现自己的脚本语言ngscript之零

    正式开始介绍前先扯点没用的. 从小玩basic长大的小朋友大多有一个梦想,就是自己实现一个basic解释器. 不过这里我实现的不是basic,而是一个语法和功能类似javascript的东西. 暂且称 ...

  4. 实现自己的脚本语言ngscript之四:代码生成

    最近的进度 ngscript测试代码 function c1(a, b, c, d) { this.a = 1; this.b = new array(); this.b[0] = 1; this.b ...

  5. 实现自己的脚本语言ngscript之二:语法分析

    ngscript的语法分析使用的是我自己的语法分析工具parseroid.与常用cc工具(yacc.bison.javacc.antlr.etc…)不同的是,parseroid生成的不是语法分析器的源 ...

  6. 实现自己的脚本语言ngscript之一:词法分析

    正则表达式的理论基础可以参考装配脑袋的 这个 自己动手开发编译器(二)正则语言和正则表达式 这个 自己动手开发编译器(三)有穷自动机 还有这个 自己动手开发编译器(四)利用DFA转换表建立扫描器 如果 ...

  7. 基于 C++ 的脚本语言 cpps 脚本

    cpps 脚本是一个基于 C++ 的脚本语言. 基础语法: if&else 接口说明 根据括号中数据判断执行相关代码. 代码演示 var i = toint(io.getc()); if(i  ...

  8. 重拾《 两周自制脚本语言 》- Eclipse插件实现语法高亮

    源码库: program-in-chinese/stone-editor-eclipse 参考: FAQ How do I write an editor for my own language? D ...

  9. L脚本语言语法手冊 0.10版

    L脚本语言语法手冊 0.10版       简  介 L脚本语言是一个轻量级的,旨在接近自然语言的编程语言,眼下支持在中文.英文基础上的编程.并可扩展为随意语种.L脚本语言的语法结构简单.程序结构相对 ...

随机推荐

  1. CSS Text文本格式

    Text Color 颜色属性被用来设置文字的颜色. 颜色是通过CSS最经常的指定: 十六进制值 - 如"#FF0000" 一个RGB值 - "RGB(255,0,0)& ...

  2. PowerDesigner 的几个使用技巧

    1.  生成sql脚本 Database→Generate Database 选择要输出的文件路径,即文件存储路径,并根据需要修改文件名,单击确定后便会生成sql脚本.   在Options选项卡里, ...

  3. php 用于检测是PC还是手机访问

    <?php$ua = strtolower($_SERVER['HTTP_USER_AGENT']);$uachar = "/(iphone|android|phone|mobile| ...

  4. Html5学习--canvas

    canvas元素的实际尺寸(宽度,高度)是由标签上的属性width和height来决定的. 这两个属性不设置时默认值为:宽度=300px,高度=150px. 如果在样式表里设置width和height ...

  5. PHP代码分离

    所谓的代码分离 其实只是一种思路,既然是一种思路 那就意味着他是有需求的 没有需求就没有解决方案 没有方案就不存在思路. 在这之前,我们制作 PHP 程序页面的时候.都是 HTML 和 PHP 混合写 ...

  6. 使用linux的GDB打印STL(vector,map,set..................)

    在linux用gdb或者cgdb计较不爽的地方是无法打印STL的东西,所有啊去网上找了找解决方案https://www.douban.com/note/182826844/?qq-pf-to=pcqq ...

  7. DELPHI TMS Advanced Charts 3.8.0.3 Full Source D6-XE6 控件分享

    仅供大家学习使用,请大家支持正版!! TMS Advanced Charts 3.8.0.3 Full Source D6-XE6 该控件用来画图标,压缩包里还有FOR INTRAWEB的版本 链接: ...

  8. WPF Canvas小例子

    源码下载:DraggingElementsInCanvas_demo.rar

  9. nutch-1.7 编译

    转载自:http://peigang.iteye.com/blog/1563288 从nutch-.3开始 本地抓取(单击) 和 分布式抓取(集群)所使用的配置文件和命令单独分开. 资源:下载地址:h ...

  10. Data guard RAC配置【二】

    2. 利用duplicate配置容灾端 1.配置容灾端oracle用户的环境变量,这里以192.166.1.61为例. export ORACLE_BASE=/opt/oracle export OR ...