`
phyeas
  • 浏览: 161563 次
  • 性别: 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和+,也不需要显式拆成右递归。我一下没看出来这个文件是对应什么工具的……

相关推荐

Global site tag (gtag.js) - Google Analytics