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

于是我去读了这本书,里面实现了两种语言,一种跟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. dense_rank()+hash提示改写优化SQL

    数据库环境:SQL SERVER 2005 今天看到一条SQL,返回10条数据,执行了50多S.刚好有空,就对它进行了优化,优化后1S出结果. 先看下原始SQL SELECT t1.line_no , ...

  2. 设计模式之 Singleton 单例模式

    先上两段代码,区别仅在于是否涉及线程安全. 首先是不涉及多线程的单例: public class Singleton { private final static Singleton INSTANCE ...

  3. js上传图片并预览

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...

  4. memcached 入门

    memcached 是什么? Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载. memcached 能够做些什么? 适用于大型网站,处理千万及的数据,而且 ...

  5. 修改Tomcat命令窗口的名字

    在运行多个tomcat窗口的时候,可以通过修改tomcat命令窗口的名字来区分不同的tomcat,修改如下: 找到tomcat下面的这个文件:tomcat_home\bin\catalina.bat, ...

  6. 实用lsof常用命令行

    1, 使用 lsof 命令行列出所有打开的文件 # lsof 这可是一个很长的列表,包括打开的文件和网络 上述屏幕截图中包含很多列,例如 PID.user.FD 和 TYPE 等等. FD - Fil ...

  7. 关于一个简单面试题(。net)

    猫大叫一声,主人被惊醒,所有的小老鼠开始逃窜. 期初想到的是事件调用方法. 在猫叫的事件中调用一对方法就可以了. 但是,当事件很多的时候 难保大家写着写着就忘记了. 总不能有 10000个人的时候调用 ...

  8. C#反射(二) 【转】

    如果没有看<C#反射(一)>.建议先看<C#反射(一)>再看这一篇.上一篇文章发表,有人评论我所写的东西比较基础.其实我也知道我也只不过是在写最基础的语法而已,之所以写它是因为 ...

  9. ASP.NET(C#)常用数据加密和解密方法汇总

    一.            数据加密的概念 1.  基本概念 2.  基本功能 3.  加密形式 二.            数据加密的项目应用和学习 1.  媒体加密:DRM 2.  文件加密:文本 ...

  10. python关键字

    python有多少关键字? >>> import keyword >>> keyword.kwlist ['and', 'as', 'assert', 'break ...