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

于是我去读了这本书,里面实现了两种语言,一种跟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. Jquery全选与反选checkbox(代码示例)

    今天在公司要实现操作权限的功能,需要根据左边的树,选择一项,判断右边的操作权限,例如,增加,修改,删除,查看等按钮的显示与隐藏: 这个功能实现思路如下: 1.操作权限:增加.修改等按钮的ID和Text ...

  2. 三步走起 提升 iOS 审核通过率 下篇

    根据2015年的数据统计情况,并结合<苹果应用商店审核指南>,互娱 iOS 预审组通过细分将预审工作划为3大模块:客户端资源检查.应用内容检查和提审资源检查. 在上一篇文章中,Bugly ...

  3. GitHub中"watch" "star" "fork"三个按钮干什么用的?

    总结下一般使用:1.想拷贝别人项目到自己帐号下就fork一下.2.持续关注别人项目更新就star一下3.watch是设置接收邮件提醒的.具体提醒有Issues and their commentsPu ...

  4. Linux 权限基础说明

      1 权限位说明 Linux文件或目录的权限位是由个9个权限位来控制的,每三位为一组,它们分别是文件属主(owner/user)读.写.执行,用户组(Group)的读.写.执行以及(Other)其他 ...

  5. php基础知识【函数】(1)数组array

    一.排序 1.sort -- 从最低到最高排序,删除原有的键名,赋予新的键名[字母比数字高] 2.rsort -- 逆向排序(最高到最低),删除原有的键名,赋予新的键名[字母比数字高] 3.asort ...

  6. 练习2 G题 - 数值统计

      Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u   Description 统计给 ...

  7. Coursera《machine learning》--(8)神经网络表述

    本笔记为Coursera在线课程<Machine Learning>中的神经网络章节的笔记. 八.神经网络:表述(Neural Networks: Representation) 本节主要 ...

  8. c# 把 颜色值Hex 转换为 Color

    原文: http://abujj.me/archives/695 Assuming you mean the HTML type RGB codes (called Hex codes, such a ...

  9. tyvj 1153 间谍网络 tarjan有向图强连通

    P1153 - 间谍网络 From ForeverBell    Normal (OI)总时限:13s    内存限制:128MB    代码长度限制:64KB 描述 Description 由于外国 ...

  10. js 作用域,变量提升

    先看下面一段代码: 代码执行的结果是: 1st alert : a = 0 2nd alert : a = undefined 5th alert : a = 0 3rd alert : a = 3 ...