`
phyeas
  • 浏览: 164650 次
  • 性别: Icon_minigender_1
  • 来自: 珠海
社区版块
存档分类
最新评论

Javascript文法之var声明

阅读更多

经过几个小时的努力,文法文件貌似终于工作正常了。文法定义的是一个js变量声明语句的文法,以此来学习文法的定义和使用。

测试输入:

var s=123;
var s="sadasd";
var s=(1);
var s=1+3*5;
var s=1+3+5;
var s=s.p;
var s=s[1];
var s=s==s;
var s=!s;
var p=p.point();
var p=p.point()-1;
var a=new Array();
var a=ss=s=d;
var regex=/avc/;
var a=ss=s;
var a=ss.x=s;

 这些输入均测试通过。

文法如下:

stmtList:
	| stmtList varDecl
;
varDecl:
	VAR ID EQ expression EXPR_END {$$=$4;printf("$$ is %d, id is %s\n", $$,$2);}
;
expression:
	assignmentExpression
	| logicalOrExpression
	| REGEX
;
assignmentExpression:
	variableAccess EQ expression
;
logicalOrExpression:
	logicalAndExpression logicalOrExpressionRight
;
logicalOrExpressionRight:
	OR logicalAndExpression
	|
;
logicalAndExpression:
	relationalExpression logicalAndExpressionRight
;
logicalAndExpressionRight:
	AND relationalExpression logicalAndExpressionRight
	|
;
relationalExpression:
	additiveExpression relationalExpressionRight
	| NOT relationalExpression
;
relationalExpressionRight:
	relationalOperator additiveExpression
	|
;
additiveExpression:
	multiplicativeExpression additiveExpressionRight
;
additiveExpressionRight:
	additiveOperator multiplicativeExpression additiveExpressionRight
	|
;
multiplicativeExpression:
	primaryExpression multiplicativeExpressionRight
;
multiplicativeExpressionRight:
	multiplicativeOperator primaryExpression multiplicativeExpressionRight
	|
;
primaryExpression:
	variableAccess
	| NUM
	| STRING
	| LPAREN expression RPAREN
	| SUB primaryExpression
	| functionCallExpression
	| newObjectExpression
;
functionCallExpression:
	variableAccess LPAREN paramsExpression RPAREN
;
paramsExpression:
	logicalOrExpression paramsExpressionRight
	|
;
paramsExpressionRight:
	COMMA paramsExpression
	|
;
newObjectExpression:
	NEW functionCallExpression
;
variableAccess:
	ID
	| ID POINT ID
	| ID LBRACK expression RBRACK
;
relationalOperator:
	LT | GT | EQEQ | LE | GE | NE | EQEQEQ | NEE
; 
additiveOperator:
	PLUS | SUB
;
multiplicativeOperator:
	MUL | DIV
;  

 文法中参考了rednaxelafx在《一个简单的语言的语法(一):用ANTLR描述语法 》中的一些文法修改得到

 

还差描述var a=function(){}的文法,由于时间关系就先不写了。明天补全。。

分享到:
评论
7 楼 RednaxelaFX 2009-09-19  
phyeas 写道
RednaxelaFX 写道
...
既然用的是bison,是LR系的,就不必那么绕弯……呵呵 ^ ^

另外,想问下如果我在声明处定义如下:
%left PLUS
然后在规则处:
expression:
    expression op expression
;
op:
    PLUS
;

这样的华expression是否会应用上面定义的优先级?

回复在此 =v=
6 楼 phyeas 2009-09-19  
RednaxelaFX 写道
...
既然用的是bison,是LR系的,就不必那么绕弯……呵呵 ^ ^

另外,想问下如果我在声明处定义如下:
%left PLUS
然后在规则处:
expression:
    expression op expression
;
op:
    PLUS
;

这样的华expression是否会应用上面定义的优先级?
5 楼 phyeas 2009-09-19  
RednaxelaFX 写道
...
既然用的是bison,是LR系的,就不必那么绕弯……呵呵 ^ ^

呵呵。已经改成使用左递归的文法。确实省下好多。谢谢
4 楼 RednaxelaFX 2009-09-19  
哦忘说了,单纯的BNF里,左结合的规则就应该写成左递归(如一般的四则运算),右结合的规则就应该写成右递归(如幂运算)。LL系的解析器一般不支持左递归的语法规则(因为会陷入无限递归),所以才要费那个力把本来应该是左递归的规则拆成右递归的。在EBNF里Kleene-star可以看作是这种拆法的语法糖,所以你会看到我之前帖里写过
additiveExpression   
    :   multiplicativeExpression ( additiveOperator multiplicativeExpression )*   
    ;

把它转换回到基本的BNF就跟你这帖里的一样了。我的意思就是说既然用的是bison,是LR系的,就不必那么绕弯……呵呵 ^ ^
3 楼 RednaxelaFX 2009-09-19  
果然么……那双目运算符的那几个表达式何必那么麻烦呢,写成左递归就完美了嘛:
additiveExpression
    : additiveExpression ADD multiplicativeExpression
    | additiveExpression SUB multiplicativeExpression
    | multiplicativeExpression
    ;

把ADD和SUB那两条子规则写成一个additiveExpression additiveOperator multiplicativeExpression也可以,拆开是为了以后你要添加语义动作时方便——加跟减的语义动作显然不一样,一加语义动作可能就要拆了。当然,也要看你的parser生成出来是要干什么,不是一定要分。

而且bison支持运算符优先级这好东西,其实根本不用写那么多个层次的加减啊乘除啊什么的,全部写在同一条大的规则就行了:
expression:
    : NUM
    | expression '+' expression
    | expression '-' expression
    | expression '*' expression
    | expression '/' expression
    | '-' expression %prec NEG
    | '(' expression ')'
    ;

省去N多麻烦……要使用运算符优先级,在文件头部的声明部分(第一个%%之前)加上相关声明就行:
%token NUM
%left '+' '-'
%left '*' '/'
%left NEG

先声明的优先级较低,后声明的较高。例子里负号的那个一元运算符用了%prec NEG来告诉bison这条子规则的优先级跟NEG一样,而NEG只是声明优先级时用的一个符号而已。
2 楼 phyeas 2009-09-19  
RednaxelaFX 写道
等等……这个是什么生成器用的语法文件?
如果是LR系那没必要把左结合的规则拆成右递归,如果是LL系那一般都支持Kleene-star和+,也不需要显式拆成右递归。我一下没看出来这个文件是对应什么工具的……

  bison。不支持()*+?等符号。。。
1 楼 RednaxelaFX 2009-09-19  
等等……这个是什么生成器用的语法文件?
如果是LR系那没必要把左结合的规则拆成右递归,如果是LL系那一般都支持Kleene-star和+,也不需要显式拆成右递归。我一下没看出来这个文件是对应什么工具的……

相关推荐

    JavaScript运行机制浅探

    JavaScript的运行机制是其独特性的体现之一。通过理解预解析、编译过程以及执行过程,开发者可以更好地避免常见的陷阱,写出更加高效和可靠的代码。此外,深入理解这些机制对于调试和解决问题也是非常有帮助的。希望...

    前端项目-pegjs.zip

    PEG.js(Parslet Expression Grammar for JavaScript)允许开发者通过定义文法来生成解析器,这个文法是基于派生式的(parsing expression grammar)。这种解析器可以理解并解析特定格式的数据,如编程语言、配置...

    random-text:使用给定的上下文无关文法生成随机文本

    Random-text使用给定的上下文无关文法生成随机文本。用法基本用法var rand = randtxt.loader().load({ 'start': '。', 'sentence': '在<place><verb>', 'subject': [ '张三', '李四', '@3 王五' ], 'place': [ '学校...

    npm-earley-cfg:在 Node.JS 中使用 Earley 算法实现上下文无关文法 (CFG)

    一个 npm 模块,包含使用 Earley 算法的上下文无关文法 (CFG) 的实现。 这是我对NPM 模块的看法,根据我的需要进行了更改。 例子 var earley = require ( 'earley-cfg' ) ; var grammar = new earley . Grammar ( ...

    js闭包详解

    JavaScript中的闭包是一种强大的语言特性,它允许函数访问和操作其词法作用域内的变量,即使在其外部作用域中调用该函数。闭包是函数及其相关的引用环境组合在一起形成的实体,它使得局部变量在函数执行完毕后依然...

    程序模型与表达_月影.pptx

    而语义则关注程序的实际行为,比如在JavaScript中的`var a = 10;`这条语句,它包含了变量声明的语法和赋值的语义。 jQuery的成功在于它提供了优秀的语法(文法)设计,如链式调用,以及良好的语义,如多态性,使得...

    SLR_Parser:基于SLR文法的四则运算解释器

    基于SLR文法的四则运算解释器 -- JS 实现演示地址: 使用方法在网页上使用首先安装gulp,nodejs与npm请自行安装 npm install -g gulp在项目目录运行 npm install再运行gulp命令,开启一个服务器 gulp打开浏览器,输入 , ...

    interpreter-preparation

    2. **变量和作用域**:JavaScript中的变量有var、let和const三种声明方式,每种都有不同的作用域规则。理解它们如何在内存中存储和访问至关重要。 3. **数据类型**:JavaScript是动态类型语言,包括基本类型(如...

    cfgjs:用于上下文无关文法的基本JS解析器

    实例化解析器 var Parser = require('./parser');var parser = new Parser();解析器导出一个类。 只需实例化它即可获得一个新的解析器。定义语法 parser.define('e', '<num1> \\+ <num2>', function (opts) { return...

    ivoire-grammar:生成语法和文本扩展。 科特迪瓦随机数生成器框架的插件

    象牙文法 生成语法和文本扩展。 随机数生成器框架的插件。 正在安装 要安装,请使用npm : npm install ivoire-grammar 或者,您可以找到源。 入门 ivoire-grammar扩展了ivoire包。 您可以直接要求它: var ...

Global site tag (gtag.js) - Google Analytics