homunculus
Advanced tools
Comparing version 0.1.9 to 0.1.10
@@ -30,7 +30,7 @@ var gulp = require('gulp'); | ||
return es.map(function (file, cb) { | ||
var target = file.path.replace('/src/', '/web/'); | ||
var target = file.path.replace(path.sep + 'src' + path.sep, path.sep + 'web' + path.sep); | ||
mkdir(path.dirname(target)); | ||
util.log(path.relative(file.cwd, file.path), '->', path.relative(file.cwd, target)); | ||
var content = file._contents; | ||
content = content.toString('utf-8', 0, content.length); | ||
content = content.toString('utf-8'); | ||
content = 'define(function(require, exports, module) {\n ' + content.replace(/\n/g, '\n ') + '\n});'; | ||
@@ -37,0 +37,0 @@ fs.writeFileSync(target, content, { encoding: 'utf-8' }); |
16
index.js
@@ -12,5 +12,7 @@ var Lexer = require('./src/lexer/Lexer'); | ||
var JsParser = require('./src/parser/js/Parser'); | ||
var Es6Parser = require('./src/parser/es6/Parser'); | ||
var CssParser = require('./src/parser/css/Parser'); | ||
var JsNode = require('./src/parser/js/Node'); | ||
var Es6Node = require('./src/parser/es6/Node'); | ||
var CssNode = require('./src/parser/css/Node'); | ||
@@ -30,2 +32,3 @@ | ||
case 'ecmascript': | ||
case 'es6': | ||
case 'as': | ||
@@ -47,2 +50,4 @@ case 'actionscript': | ||
return JsParser; | ||
case 'es6': | ||
return Es6Parser; | ||
case 'css': | ||
@@ -61,2 +66,4 @@ return CssParser; | ||
return JsNode; | ||
case 'es6': | ||
return Es6Node; | ||
case 'css': | ||
@@ -93,2 +100,3 @@ return CssNode; | ||
case 'ecmascript': | ||
case 'es6': | ||
case 'as': | ||
@@ -119,2 +127,4 @@ case 'actionscript': | ||
return new JsParser(exports.getLexer(lan)); | ||
case 'es6': | ||
return new Es6Parser(exports.getLexer(lan)); | ||
case 'css': | ||
@@ -138,2 +148,6 @@ return new CssParser(exports.getLexer(lan)); | ||
} | ||
}; | ||
}; | ||
var madge = require('madge'); | ||
var dependencyObject = madge('./web'); | ||
console.log(dependencyObject.tree); |
{ | ||
"name": "homunculus", | ||
"version": "0.1.9", | ||
"version": "0.1.10", | ||
"description": "A lexer&parser by Javascript", | ||
@@ -23,2 +23,3 @@ "maintainers": [ | ||
"src/parser/js", | ||
"src/parser/es6", | ||
"src/util" | ||
@@ -25,0 +26,0 @@ ] |
@@ -15,3 +15,3 @@ # A lexer&parser by Javascript | ||
* getClass(type:String, lan:String):class | ||
* tyep: lexer parser node context token | ||
* type: lexer parser node context token | ||
* lan: js javascript es ecmascript as actionscript css | ||
@@ -18,0 +18,0 @@ * getLexer(lan:String):object |
@@ -66,10 +66,8 @@ var Class = require('../../util/Class'); | ||
}).statics({ | ||
PROGRAM: 'program', | ||
ELEMS: 'elems', | ||
ELEM: 'elem', | ||
CSTSTMT: 'cststmt', | ||
LETSTMT: 'letstmt', | ||
SCRIPT: 'script', | ||
SCRIPTBODY: 'scriptbody', | ||
VARSTMT: 'varstmt', | ||
VARDECL: 'vardecl', | ||
FNBODY: 'fnbody', | ||
BLOCKSTMT: 'blockstmt', | ||
BLOCK: 'block', | ||
@@ -109,2 +107,3 @@ ITERSTMT: 'iterstmt', | ||
CACH: 'cach', | ||
CACHPARAM: 'cachparam', | ||
FINL: 'finl', | ||
@@ -131,3 +130,2 @@ FNDECL: 'fndecl', | ||
PROPTASSIGN: 'proptassign', | ||
PROPTNAME: 'proptname', | ||
PROPTSETS: 'propsets', | ||
@@ -140,12 +138,21 @@ ARGS: 'args', | ||
CALLEXPR: 'callexpr', | ||
SPREAD: 'spread', | ||
ARRCMPH: 'arrcmph', | ||
CMPHFOR: 'cmphfor', | ||
INITLZ: 'initlz', | ||
BINDID: 'bindid', | ||
ARRBINDPAT: 'arrbindpat', | ||
OBJBINDPAT: 'objbindpat', | ||
BINDPROPT: 'bindpropt', | ||
SINGLENAME: 'singlename', | ||
BINDELEM: 'bindelem', | ||
BINDREST: 'bindrest', | ||
BINDID: 'bindid', | ||
SPREAD: 'spread', | ||
ARRCMPH: 'arrcmph', | ||
CMPHFOR: 'cmphfor', | ||
PROPTNAME: 'proptname', | ||
SINGLENAME: 'singlename', | ||
BINDPROPT: 'bindpropt', | ||
LTRPROPT: 'ltrpropt', | ||
CMPTPROPT: 'cmptpropt', | ||
LEXDECL: 'lexdecl', | ||
LEXBIND: 'lexbind', | ||
FMPARAMS: 'fmparams', | ||
CMPHIF: 'cmphif', | ||
getKey: function(s) { | ||
@@ -152,0 +159,0 @@ if(!s) { |
@@ -9,2 +9,17 @@ var Class = require('../../util/Class'); | ||
S[Token.BLANK] = S[Token.TAB] = S[Token.COMMENT] = S[Token.LINE] = S[Token.ENTER] = true; | ||
var NOASSIGN = {}; | ||
NOASSIGN[Node.CNDTEXPR] | ||
= NOASSIGN[Node.LOGOREXPR] | ||
= NOASSIGN[Node.LOGANDEXPR] | ||
= NOASSIGN[Node.BITOREXPR] | ||
= NOASSIGN[Node.BITXOREXPR] | ||
= NOASSIGN[Node.BITANDEXPR] | ||
= NOASSIGN[Node.EQEXPR] | ||
= NOASSIGN[Node.RELTEXPR] | ||
= NOASSIGN[Node.SHIFTEXPR] | ||
= NOASSIGN[Node.ADDEXPR] | ||
= NOASSIGN[Node.MTPLEXPR] | ||
= NOASSIGN[Node.UNARYEXPR] | ||
= NOASSIGN[Node.POSTFIXEXPR] | ||
= true; | ||
var Parser = Class(function(lexer) { | ||
@@ -15,3 +30,3 @@ this.init(lexer); | ||
this.lexer.parse(code); | ||
this.tree = this.program(); | ||
this.tree = this.script(); | ||
return this.tree; | ||
@@ -44,3 +59,3 @@ }, | ||
}, | ||
program: function() { | ||
script: function() { | ||
this.tokens = this.lexer.tokens(); | ||
@@ -51,20 +66,24 @@ this.length = this.tokens.length; | ||
} | ||
var node = new Node(Node.PROGRAM); | ||
var node = new Node(Node.SCRIPT); | ||
if(this.look) { | ||
node.add(this.scriptbody()); | ||
} | ||
return node; | ||
}, | ||
scriptbody: function() { | ||
var node = new Node(Node.SCRIPTBODY); | ||
while(this.look) { | ||
node.add(this.element()); | ||
node.add(this.stmtlitem()); | ||
} | ||
return node; | ||
}, | ||
element: function(allowSuper) { | ||
if(this.look.content() == 'function') { | ||
return this.fndecl(); | ||
stmtlitem: function() { | ||
if(['function', 'class', 'let', 'const'].indexOf(this.look.content()) > -1) { | ||
return this.decl(); | ||
} | ||
else if(this.look.content() == 'class') { | ||
return this.classdecl(); | ||
} | ||
else { | ||
return this.stmt(allowSuper); | ||
return this.stmt(); | ||
} | ||
}, | ||
stmt: function(allowSuper) { | ||
decl: function() { | ||
if(!this.look) { | ||
@@ -75,9 +94,19 @@ this.error(); | ||
case 'let': | ||
return this.letstmt(); | ||
case 'const': | ||
return this.cststmt(); | ||
return this.lexdecl(); | ||
case 'function': | ||
return this.fndecl(); | ||
case 'class': | ||
return this.classdecl(); | ||
} | ||
}, | ||
stmt: function() { | ||
if(!this.look) { | ||
this.error(); | ||
} | ||
switch(this.look.content()) { | ||
case 'var': | ||
return this.varstmt(); | ||
case '{': | ||
return this.block(); | ||
return this.blockstmt(); | ||
case ';': | ||
@@ -107,9 +136,11 @@ return this.emptstmt(); | ||
return this.debstmt(); | ||
case 'super': | ||
if(!allowSuper) { | ||
this.error('super must in a class'); | ||
} | ||
return this.superstmt(); | ||
case 'import': | ||
return this.imptstmt(); | ||
case 'yield': | ||
return this.labstmt(); | ||
// case 'super': | ||
// if(!allowSuper) { | ||
// this.error('super must in a class'); | ||
// } | ||
// return this.superstmt(); | ||
// case 'import': | ||
// return this.imptstmt(); | ||
default: | ||
@@ -137,35 +168,44 @@ if(this.look.type() == Token.ID) { | ||
}, | ||
cststmt: function(noSem) { | ||
var node = new Node(Node.CSTSTMT); | ||
node.add( | ||
this.match('const'), | ||
this.vardecl() | ||
); | ||
lexdecl: function() { | ||
var node = new Node(Node.LEXDECL); | ||
if(this.look.content() == 'let') { | ||
node.add(this.match()); | ||
} | ||
else if(this.look.content() == 'const') { | ||
node.add(this.match()); | ||
} | ||
else { | ||
this.error(); | ||
} | ||
node.add(this.lexbind()); | ||
while(this.look && this.look.content() == ',') { | ||
node.add( | ||
this.match(), | ||
this.vardecl() | ||
this.lexbind() | ||
); | ||
} | ||
if(!noSem) { | ||
node.add(this.match(';')); | ||
} | ||
return node; | ||
}, | ||
letstmt: function(noSem) { | ||
var node = new Node(Node.LETSTMT); | ||
node.add( | ||
this.match('let'), | ||
this.vardecl() | ||
); | ||
while(this.look && this.look.content() == ',') { | ||
node.add( | ||
this.match(), | ||
this.vardecl() | ||
); | ||
lexbind: function() { | ||
var node = new Node(Node.LEXBIND); | ||
this.declnode(node); | ||
return node; | ||
}, | ||
declnode: function(node) { | ||
if(!this.look) { | ||
this.error('missing variable name'); | ||
} | ||
if(!noSem) { | ||
node.add(this.match(';')); | ||
if(['[', '{'].indexOf(this.look.content()) > -1) { | ||
node.add(this.bindpat()); | ||
if(!this.look || this.look.content() != '=') { | ||
this.error('missing = in destructuring declaration'); | ||
} | ||
node.add(this.initlz()); | ||
} | ||
return node; | ||
else { | ||
node.add(this.bindid('missing variable name')); | ||
if(this.look && this.look.content() == '=') { | ||
node.add(this.initlz()); | ||
} | ||
} | ||
}, | ||
@@ -191,20 +231,10 @@ varstmt: function(noSem) { | ||
var node = new Node(Node.VARDECL); | ||
if(!this.look) { | ||
this.error('missing variable name'); | ||
} | ||
if(['[', '{'].indexOf(this.look.content()) > -1) { | ||
node.add(this.bindpat()); | ||
if(!this.look || this.look.content() != '=') { | ||
this.error('missing = in destructuring declaration'); | ||
} | ||
node.add(this.assign()); | ||
} | ||
else { | ||
node.add(this.match(Token.ID, 'missing variable name')); | ||
if(this.look && this.look.content() == '=') { | ||
node.add(this.assign()); | ||
} | ||
} | ||
this.declnode(node); | ||
return node; | ||
}, | ||
bindid: function(msg) { | ||
var node = new Node(Node.BINDID); | ||
node.add(this.match(Token.ID, msg)); | ||
return node; | ||
}, | ||
bindpat: function() { | ||
@@ -217,2 +247,5 @@ if(this.look.content() == '[') { | ||
} | ||
else { | ||
this.error(); | ||
} | ||
}, | ||
@@ -234,3 +267,3 @@ arrbindpat: function() { | ||
if(this.look.content() == '...') { | ||
node.add(this.restparam()); | ||
node.add(this.bindrest()); | ||
} | ||
@@ -245,3 +278,3 @@ node.add(this.match(']', 'missing ] after element list')); | ||
if(this.look && this.look.content() == '=') { | ||
node.add(this.assign()); | ||
node.add(this.initlz()); | ||
} | ||
@@ -256,8 +289,16 @@ } | ||
var node = new Node(Node.SINGLENAME); | ||
node.add(this.match(Token.ID)); | ||
node.add(this.bindid()); | ||
if(this.look && this.look.content() == '=') { | ||
node.add(this.assign()); | ||
node.add(this.initlz()); | ||
} | ||
return node; | ||
}, | ||
bindrest: function() { | ||
var node = new Node(Node.BINDREST); | ||
node.add( | ||
this.match('...'), | ||
this.bindid('no parameter name after ...') | ||
); | ||
return node; | ||
}, | ||
objbindpat: function() { | ||
@@ -277,2 +318,3 @@ var node = new Node(Node.OBJBINDPAT); | ||
var node = new Node(Node.BINDPROPT); | ||
//只能是singlename或者properyname | ||
switch(this.look.type()) { | ||
@@ -284,6 +326,17 @@ case Token.ID: | ||
default: | ||
this.error('invalid property id'); | ||
if(this.look.content() != '[') { | ||
this.error('invalid property id'); | ||
} | ||
} | ||
//[为PropertyName左推导 | ||
if(this.look.content() == '[') { | ||
node.add( | ||
this.proptname(), | ||
this.match(':'), | ||
this.bindelem() | ||
); | ||
return node; | ||
} | ||
//根据LL2分辨是PropertyName[?Yield, ?GeneratorParameter] : BindingElement[?Yield, ?GeneratorParameter] | ||
//还是SingleNameBinding [?Yield, ?GeneratorParameter] | ||
//还是SingleNameBinding[?Yield, ?GeneratorParameter] | ||
for(var i = this.index; i < this.length; i++) { | ||
@@ -293,4 +346,7 @@ var next = this.tokens[i]; | ||
if(next.content() == ':') { | ||
node.add(this.match(), this.match()); | ||
node.add(this.bindelem()); | ||
node.add( | ||
this.proptname(), | ||
this.match(':'), | ||
this.bindelem() | ||
); | ||
} | ||
@@ -314,7 +370,12 @@ else { | ||
}, | ||
block: function() { | ||
blockstmt: function() { | ||
var node = new Node(Node.BLOCKSTMT); | ||
node.add(this.block()); | ||
return node; | ||
}, | ||
block: function(msg) { | ||
var node = new Node(Node.BLOCK); | ||
node.add(this.match('{')); | ||
node.add(this.match('{', msg)); | ||
while(this.look && this.look.content() != '}') { | ||
node.add(this.stmt()); | ||
node.add(this.stmtlitem()); | ||
} | ||
@@ -498,6 +559,6 @@ node.add(this.match('}', 'missing } in compound statement')); | ||
node.add( | ||
this.match('with'), | ||
this.match('with', 'missing ( before with-statement object'), | ||
this.match('('), | ||
this.expr(), | ||
this.match(')'), | ||
this.match(')', 'missing ) after with-statement object'), | ||
this.stmt() | ||
@@ -563,4 +624,9 @@ ); | ||
var node = new Node(Node.LABSTMT); | ||
if(this.look.content() == 'yield') { | ||
node.add(this.match()); | ||
} | ||
else { | ||
node.add(this.match(Token.ID)); | ||
} | ||
node.add( | ||
this.match(Token.ID), | ||
this.match(':'), | ||
@@ -584,3 +650,3 @@ this.stmt() | ||
this.match('try'), | ||
this.block() | ||
this.block('missing { before try block') | ||
); | ||
@@ -606,10 +672,20 @@ if(this.look && this.look.content() == 'catch') { | ||
node.add( | ||
this.match('catch'), | ||
this.match('('), | ||
this.match(Token.ID, 'missing identifier in catch'), | ||
this.match(')'), | ||
this.block() | ||
this.match('catch', 'missing catch or finally after try'), | ||
this.match('(', 'missing ( before catch'), | ||
this.cachparam(), | ||
this.match(')', 'missing ) after catch'), | ||
this.block('missing { before catch block') | ||
); | ||
return node; | ||
}, | ||
cachparam: function() { | ||
var node = new Node(Node.CACHPARAM); | ||
if(['[', '{'].indexOf(this.look.content()) > -1) { | ||
node.add(this.bindpat()); | ||
} | ||
else { | ||
node.add(this.bindid('missing identifier in catch')); | ||
} | ||
return node; | ||
}, | ||
finl: function() { | ||
@@ -619,3 +695,3 @@ var node = new Node(Node.FINL); | ||
this.match('finally'), | ||
this.block() | ||
this.block('missing { before finally block') | ||
); | ||
@@ -664,16 +740,9 @@ return node; | ||
this.match('function'), | ||
this.match(Token.ID, 'function statement requires a name'), | ||
this.match('(') | ||
); | ||
if(!this.look) { | ||
this.error('missing formal parameter'); | ||
} | ||
if(this.look.content() != ')') { | ||
node.add(this.fnparams()); | ||
} | ||
node.add( | ||
this.match(')'), | ||
this.bindid('function statement requires a name'), | ||
this.match('(', 'missing ( before formal parameters'), | ||
this.fmparams(), | ||
this.match(')', 'missing ) after formal parameters'), | ||
this.match('{'), | ||
this.fnbody(), | ||
this.match('}') | ||
this.match('}', 'missing } after function body') | ||
); | ||
@@ -684,3 +753,5 @@ return node; | ||
var node = new Node(Node.FNEXPR); | ||
node.add(this.match('function')); | ||
node.add( | ||
this.match('function') | ||
); | ||
if(!this.look) { | ||
@@ -690,33 +761,28 @@ this.error('missing formal parameter'); | ||
if(this.look.type() == Token.ID) { | ||
node.add(this.match()); | ||
node.add(this.bindid()); | ||
} | ||
node.add(this.match('(')); | ||
if(!this.look) { | ||
this.error(); | ||
} | ||
if(this.look.content() != ')') { | ||
node.add(this.fnparams()); | ||
} | ||
node.add( | ||
this.match(')'), | ||
this.match('(', 'missing ( before formal parameters'), | ||
this.fmparams(), | ||
this.match(')', 'missing ) after formal parameters'), | ||
this.match('{'), | ||
this.fnbody(), | ||
this.match('}', 'missing } in compound statement') | ||
this.match('}', 'missing } after function body') | ||
); | ||
return node; | ||
}, | ||
fnparams: function() { | ||
var node = new Node(Node.FNPARAMS); | ||
while(this.look && this.look.content() != ')' && this.look.content() != '...') { | ||
node.add(this.match(Token.ID, 'missing formal parameter')); | ||
if(this.look) { | ||
if(this.look.content() == ',') { | ||
fmparams: function() { | ||
var node = new Node(Node.FMPARAMS); | ||
if(!this.look) { | ||
this.error('missing formal parameter'); | ||
} | ||
while(this.look && this.look.content() != ')') { | ||
if(this.look.content() == '...') { | ||
break; | ||
} | ||
else { | ||
node.add(this.bindelem()); | ||
if(this.look && this.look.content() == ',') { | ||
node.add(this.match()); | ||
} | ||
else if(this.look.content() == '=') { | ||
node.add(this.bindelement()); | ||
if(this.look && this.look.content() == ',') { | ||
node.add(this.match()); | ||
} | ||
} | ||
} | ||
@@ -728,20 +794,10 @@ } | ||
if(this.look.content() == '...') { | ||
node.add(this.restparam()); | ||
node.add(this.bindrest()); | ||
} | ||
return node; | ||
}, | ||
bindelement: function() { | ||
var node = new Node(Node.BINDELEMENT); | ||
node.add(this.match('='), this.assignexpr()); | ||
return node; | ||
}, | ||
restparam: function() { | ||
var node = new Node(Node.RESTPARAM); | ||
node.add(this.match('...'), this.match(Token.ID)); | ||
return node; | ||
}, | ||
fnbody: function(allowSuper) { | ||
fnbody: function() { | ||
var node = new Node(Node.FNBODY); | ||
while(this.look && this.look.content() != '}') { | ||
node.add(this.element(allowSuper)); | ||
node.add(this.stmtlitem()); | ||
} | ||
@@ -834,5 +890,13 @@ return node; | ||
}, | ||
initlz: function(noIn) { | ||
var node = new Node(Node.INITLZ); | ||
node.add( | ||
this.match('='), | ||
this.assignexpr(noIn) | ||
); | ||
return node; | ||
}, | ||
assignexpr: function(noIn) { | ||
var node = new Node(Node.ASSIGNEXPR), | ||
cndt = this.cndtexpr(noIn); | ||
var node = new Node(Node.ASSIGNEXPR); | ||
var cndt = this.cndtexpr(noIn); | ||
if(this.look && { | ||
@@ -851,3 +915,3 @@ '*=': true, | ||
'=': true | ||
}.hasOwnProperty(this.look.content())) { | ||
}.hasOwnProperty(this.look.content()) && !NOASSIGN.hasOwnProperty(cndt.name())) { | ||
node.add(cndt, this.match(), this.assignexpr(noIn)); | ||
@@ -1139,3 +1203,3 @@ } | ||
this.match(), | ||
this.match(Token.ID) | ||
this.match(Token.ID, 'missing name after . operator') | ||
); | ||
@@ -1175,3 +1239,3 @@ } | ||
this.match(), | ||
this.match(Token.ID) | ||
this.match(Token.ID, 'missing name after . operator') | ||
); | ||
@@ -1215,3 +1279,3 @@ } | ||
this.match(), | ||
this.match(Token.ID) | ||
this.match(Token.ID, 'missing name after . operator') | ||
); | ||
@@ -1269,7 +1333,2 @@ } | ||
}, | ||
bindid: function() { | ||
var node = new Node(Node.BINDID); | ||
node.add(this.match('...'), this.assignexpr()); | ||
return node; | ||
}, | ||
arrinit: function() { | ||
@@ -1295,2 +1354,14 @@ //根据LL2分辨是arrltr还是arrcmph | ||
node.add(this.cmphfor()); | ||
while(this.look && this.look.content() != ']') { | ||
if(this.look.content() == 'for') { | ||
node.add(this.cmphfor()); | ||
} | ||
else if(this.look.content() == 'if') { | ||
node.add(this.cmphif()); | ||
} | ||
else { | ||
node.add(this.assignexpr()); | ||
break; | ||
} | ||
} | ||
node.add(this.match(']', 'missing ] after element list')); | ||
@@ -1301,5 +1372,33 @@ return node; | ||
var node = new Node(Node.CMPHFOR); | ||
node.add(this.match('for')); | ||
node.add( | ||
this.match('for'), | ||
this.match('('), | ||
this.forbind(), | ||
this.match('of'), | ||
this.assignexpr(), | ||
this.match(')') | ||
); | ||
return node; | ||
}, | ||
forbind: function() { | ||
if(!this.look) { | ||
this.error(); | ||
} | ||
if(['[', '{'].indexOf(this.look.content()) > -1) { | ||
return this.bindpat(); | ||
} | ||
else { | ||
return this.bindid(); | ||
} | ||
}, | ||
cmphif: function() { | ||
var node = new Node(Node.CMPHIF); | ||
node.add( | ||
this.match('if'), | ||
this.match('('), | ||
this.assignexpr(), | ||
this.match(')') | ||
); | ||
return node; | ||
}, | ||
arrltr: function() { | ||
@@ -1415,15 +1514,34 @@ var node = new Node(Node.ARRLTR); | ||
var node = new Node(Node.PROPTNAME); | ||
if(this.look) { | ||
switch(this.look.type()) { | ||
case Token.ID: | ||
case Token.NUMBER: | ||
case Token.STRING: | ||
node.add(this.match()); | ||
break; | ||
default: | ||
this.error('missing name after . operator'); | ||
} | ||
if(!this.look) { | ||
this.error('invalid property id'); | ||
} | ||
if(this.look.content() == '[') { | ||
node.add(this.cmptpropt()); | ||
} | ||
else { | ||
node.add(this.ltrpropt()); | ||
} | ||
return node; | ||
}, | ||
ltrpropt: function() { | ||
var node = new Node(Node.LTRPROPT); | ||
switch(this.look.type()) { | ||
case Token.ID: | ||
case Token.NUMBER: | ||
case Token.STRING: | ||
node.add(this.match()); | ||
return node; | ||
default: | ||
this.error('invalid property id'); | ||
} | ||
}, | ||
cmptpropt: function() { | ||
var node = new Node(Node.CMPTPROPT); | ||
node.add( | ||
this.match('['), | ||
this.assignexpr(), | ||
this.match(']') | ||
); | ||
return node; | ||
}, | ||
propsets: function() { | ||
@@ -1454,5 +1572,5 @@ var node = new Node(Node.PROPTSETS); | ||
} | ||
if(this.look && this.look.content() == '...') { | ||
node.add(this.bindid()); | ||
} | ||
// if(this.look && this.look.content() == '...') { | ||
// node.add(this.bindid()); | ||
// } | ||
return node; | ||
@@ -1459,0 +1577,0 @@ }, |
@@ -67,6 +67,3 @@ var Class = require('../../util/Class'); | ||
PROGRAM: 'program', | ||
ELEMS: 'elems', | ||
ELEM: 'elem', | ||
CSTSTMT: 'cststmt', | ||
LETSTMT: 'letstmt', | ||
VARSTMT: 'varstmt', | ||
@@ -79,13 +76,3 @@ VARDECL: 'vardecl', | ||
FNPARAMS: 'fnparams', | ||
BINDELEMENT: 'bindelement', | ||
RESTPARAM: 'restparam', | ||
EXPR: 'expr', | ||
CLASSDECL: 'classdecl', | ||
CLASSTAIL: 'classtail', | ||
HERITAGE: 'heritage', | ||
CLASSBODY: 'classbody', | ||
METHOD: 'method', | ||
SUPERSTMT: 'superstmt', | ||
GETFN: 'getfn', | ||
SETFN: 'setfn', | ||
PROGRAM: 'program', | ||
@@ -131,20 +118,7 @@ STMT: 'stmt', | ||
PROPTASSIGN: 'proptassign', | ||
PROPTNAME: 'proptname', | ||
PROPTSETS: 'propsets', | ||
ARGS: 'args', | ||
ARGLIST: 'arglist', | ||
IMPTSTMT: 'imptstmt', | ||
POSTFIXEXPR: 'postfixexpr', | ||
NEWEXPR: 'newexpr', | ||
CALLEXPR: 'callexpr', | ||
ARRBINDPAT: 'arrbindpat', | ||
OBJBINDPAT: 'objbindpat', | ||
BINDPROPT: 'bindpropt', | ||
SINGLENAME: 'singlename', | ||
BINDELEM: 'bindelem', | ||
BINDREST: 'bindrest', | ||
BINDID: 'bindid', | ||
SPREAD: 'spread', | ||
ARRCMPH: 'arrcmph', | ||
CMPHFOR: 'cmphfor', | ||
getKey: function(s) { | ||
@@ -151,0 +125,0 @@ if(!s) { |
@@ -9,2 +9,17 @@ var Class = require('../../util/Class'); | ||
S[Token.BLANK] = S[Token.TAB] = S[Token.COMMENT] = S[Token.LINE] = S[Token.ENTER] = true; | ||
var NOASSIGN = {}; | ||
NOASSIGN[Node.CNDTEXPR] | ||
= NOASSIGN[Node.LOGOREXPR] | ||
= NOASSIGN[Node.LOGANDEXPR] | ||
= NOASSIGN[Node.BITOREXPR] | ||
= NOASSIGN[Node.BITXOREXPR] | ||
= NOASSIGN[Node.BITANDEXPR] | ||
= NOASSIGN[Node.EQEXPR] | ||
= NOASSIGN[Node.RELTEXPR] | ||
= NOASSIGN[Node.SHIFTEXPR] | ||
= NOASSIGN[Node.ADDEXPR] | ||
= NOASSIGN[Node.MTPLEXPR] | ||
= NOASSIGN[Node.UNARYEXPR] | ||
= NOASSIGN[Node.POSTFIXEXPR] | ||
= true; | ||
var Parser = Class(function(lexer) { | ||
@@ -536,4 +551,4 @@ this.init(lexer); | ||
assignexpr: function(noIn) { | ||
var node = new Node(Node.ASSIGNEXPR), | ||
cndt = this.cndtexpr(noIn); | ||
var node = new Node(Node.ASSIGNEXPR); | ||
var cndt = this.cndtexpr(noIn); | ||
if(this.look && { | ||
@@ -552,3 +567,3 @@ '*=': true, | ||
'=': true | ||
}.hasOwnProperty(this.look.content())) { | ||
}.hasOwnProperty(this.look.content()) && !NOASSIGN.hasOwnProperty(cndt.name())) { | ||
node.add(cndt, this.match(), this.assignexpr(noIn)); | ||
@@ -840,3 +855,3 @@ } | ||
this.match(), | ||
this.match(Token.ID) | ||
this.match(Token.ID, 'missing name after . operator') | ||
); | ||
@@ -876,3 +891,3 @@ } | ||
this.match(), | ||
this.match(Token.ID) | ||
this.match(Token.ID, 'missing name after . operator') | ||
); | ||
@@ -916,3 +931,3 @@ } | ||
this.match(), | ||
this.match(Token.ID) | ||
this.match(Token.ID, 'missing name after . operator') | ||
); | ||
@@ -919,0 +934,0 @@ } |
@@ -8,4 +8,6 @@ var homunculus = require('../'); | ||
var JsParser = require('../src/parser/js/Parser'); | ||
var Es6Parser = require('../src/parser/es6/Parser'); | ||
var CssParser = require('../src/parser/css/Parser'); | ||
var JsNode = require('../src/parser/js/Node'); | ||
var Es6Node = require('../src/parser/es6/Node'); | ||
var CssNode = require('../src/parser/css/Node'); | ||
@@ -21,2 +23,3 @@ var Token = require('../src/lexer/Token'); | ||
expect(homunculus.getClass('lexer', 'ecmascript')).to.be(Lexer); | ||
expect(homunculus.getClass('lexer', 'es6')).to.be(Lexer); | ||
expect(homunculus.getClass('lexer', 'as')).to.be(Lexer); | ||
@@ -31,2 +34,3 @@ expect(homunculus.getClass('lexer', 'actionscript')).to.be(Lexer); | ||
expect(homunculus.getClass('parser', 'ecmascript')).to.be(JsParser); | ||
expect(homunculus.getClass('parser', 'es6')).to.be(Es6Parser); | ||
@@ -39,2 +43,3 @@ expect(homunculus.getClass('parser', 'css')).to.be(CssParser); | ||
expect(homunculus.getClass('node', 'ecmascript')).to.be(JsNode); | ||
expect(homunculus.getClass('node', 'es6')).to.be(Es6Node); | ||
@@ -55,2 +60,3 @@ expect(homunculus.getClass('node', 'css')).to.be(CssNode); | ||
expect(homunculus.getLexer('ecmascript')).to.be.a(Lexer); | ||
expect(homunculus.getLexer('es6')).to.be.a(Lexer); | ||
expect(homunculus.getLexer('as')).to.be.a(Lexer); | ||
@@ -66,2 +72,3 @@ expect(homunculus.getLexer('actionscript')).to.be.a(Lexer); | ||
expect(homunculus.getParser('ecmascript')).to.be.a(JsParser); | ||
expect(homunculus.getParser('es6')).to.be.a(Es6Parser); | ||
@@ -68,0 +75,0 @@ expect(homunculus.getParser('css')).to.be.a(CssParser); |
@@ -8,5 +8,36 @@ var homunculus = require('../'); | ||
var Token = homunculus.getClass('token'); | ||
var Parser = homunculus.getClass('parser', 'js'); | ||
var JsNode = homunculus.getClass('node', 'js'); | ||
var Parser = homunculus.getClass('parser', 'es6'); | ||
var JsNode = homunculus.getClass('node', 'es6'); | ||
var res; | ||
var index; | ||
function jion(node, ignore) { | ||
res = ''; | ||
index = 0; | ||
while(ignore[index]) { | ||
res += ignore[index++].content(); | ||
} | ||
recursion(node, ignore); | ||
return res; | ||
} | ||
function recursion(node, ignore) { | ||
var isToken = node.name() == JsNode.TOKEN; | ||
var isVirtual = isToken && node.token().type() == Token.VIRTUAL; | ||
if(isToken) { | ||
if(!isVirtual) { | ||
var token = node.token(); | ||
res += token.content(); | ||
while(ignore[++index]) { | ||
res += ignore[index].content(); | ||
} | ||
} | ||
} | ||
else { | ||
node.leaves().forEach(function(leaf, i) { | ||
recursion(leaf, ignore); | ||
}); | ||
} | ||
} | ||
function tree(node, arr) { | ||
@@ -31,2 +62,299 @@ arr = arr || []; | ||
return arr; | ||
} | ||
} | ||
describe('es6parser', function() { | ||
describe('simple test', function () { | ||
it('varstmt no assign', function() { | ||
var parser = homunculus.getParser('es6'); | ||
var node = parser.parse('var a;'); | ||
expect(tree(node)).to.eql([JsNode.SCRIPT,[JsNode.SCRIPTBODY,[JsNode.VARSTMT,["var",JsNode.VARDECL,[JsNode.BINDID,["a"]],";"]]]]); | ||
}); | ||
it('varstmt with assign', function() { | ||
var parser = homunculus.getParser('es6'); | ||
var node = parser.parse('var a = 1;'); | ||
expect(tree(node)).to.eql([JsNode.SCRIPT,[JsNode.SCRIPTBODY,[JsNode.VARSTMT,["var",JsNode.VARDECL,[JsNode.BINDID,["a"],JsNode.INITLZ,["=",JsNode.PRMREXPR,["1"]]],";"]]]]); | ||
}); | ||
it('varstmt with multi', function() { | ||
var parser = homunculus.getParser('es6'); | ||
var node = parser.parse('var a, b = 1;'); | ||
expect(tree(node)).to.eql([JsNode.SCRIPT,[JsNode.SCRIPTBODY,[JsNode.VARSTMT,["var",JsNode.VARDECL,[JsNode.BINDID,["a"]],",",JsNode.VARDECL,[JsNode.BINDID,["b"],JsNode.INITLZ,["=",JsNode.PRMREXPR,["1"]]],";"]]]]); | ||
}); | ||
it('destructuring array', function() { | ||
var parser = homunculus.getParser('es6'); | ||
var node = parser.parse('var [a] = [1]'); | ||
expect(tree(node)).to.eql([JsNode.SCRIPT,[JsNode.SCRIPTBODY,[JsNode.VARSTMT,["var",JsNode.VARDECL,[JsNode.ARRBINDPAT,["[",JsNode.SINGLENAME,[JsNode.BINDID,["a"]],"]"],JsNode.INITLZ,["=",JsNode.PRMREXPR,[JsNode.ARRLTR,["[",JsNode.PRMREXPR,["1"],"]"]]]]]]]]); | ||
}); | ||
it('destructuring with restparam', function() { | ||
var parser = homunculus.getParser('es6'); | ||
var node = parser.parse('var [a, ...b] = [1, 2, 3]'); | ||
expect(tree(node)).to.eql([JsNode.SCRIPT,[JsNode.SCRIPTBODY,[JsNode.VARSTMT,["var",JsNode.VARDECL,[JsNode.ARRBINDPAT,["[",JsNode.SINGLENAME,[JsNode.BINDID,["a"]],",",JsNode.BINDREST,["...",JsNode.BINDID,["b"]],"]"],JsNode.INITLZ,["=",JsNode.PRMREXPR,[JsNode.ARRLTR,["[",JsNode.PRMREXPR,["1"],",",JsNode.PRMREXPR,["2"],",",JsNode.PRMREXPR,["3"],"]"]]]]]]]]); | ||
}); | ||
it('destructuring with default value', function() { | ||
var parser = homunculus.getParser('es6'); | ||
var node = parser.parse('var [a = 1, [b] = [2]] = [, []]'); | ||
expect(tree(node)).to.eql([JsNode.SCRIPT,[JsNode.SCRIPTBODY,[JsNode.VARSTMT,["var",JsNode.VARDECL,[JsNode.ARRBINDPAT,["[",JsNode.SINGLENAME,[JsNode.BINDID,["a"],JsNode.INITLZ,["=",JsNode.PRMREXPR,["1"]]],",",JsNode.BINDELEM,[JsNode.ARRBINDPAT,["[",JsNode.SINGLENAME,[JsNode.BINDID,["b"]],"]"],JsNode.INITLZ,["=",JsNode.PRMREXPR,[JsNode.ARRLTR,["[",JsNode.PRMREXPR,["2"],"]"]]]],"]"],JsNode.INITLZ,["=",JsNode.PRMREXPR,[JsNode.ARRLTR,["[",",",JsNode.PRMREXPR,[JsNode.ARRLTR,["[","]"]],"]"]]]]]]]]); | ||
}); | ||
it('destructuring object', function() { | ||
var parser = homunculus.getParser('es6'); | ||
var node = parser.parse('var {x, y = 1, "f": [z]} = {}'); | ||
expect(tree(node)).to.eql([JsNode.SCRIPT,[JsNode.SCRIPTBODY,[JsNode.VARSTMT,["var",JsNode.VARDECL,[JsNode.OBJBINDPAT,["{",JsNode.BINDPROPT,[JsNode.SINGLENAME,[JsNode.BINDID,["x"]]],",",JsNode.BINDPROPT,[JsNode.SINGLENAME,[JsNode.BINDID,["y"],JsNode.INITLZ,["=",JsNode.PRMREXPR,["1"]]]],",",JsNode.BINDPROPT,[JsNode.PROPTNAME,[JsNode.LTRPROPT,["\"f\""]],":",JsNode.BINDELEM,[JsNode.ARRBINDPAT,["[",JsNode.SINGLENAME,[JsNode.BINDID,["z"]],"]"]]],"}"],JsNode.INITLZ,["=",JsNode.PRMREXPR,[JsNode.OBJLTR,["{","}"]]]]]]]]); | ||
}); | ||
it('destructuring complex', function() { | ||
var parser = homunculus.getParser('es6'); | ||
var node = parser.parse('var [x, {"a":[y=1,{z=2},...o]}] = []'); | ||
expect(tree(node)).to.eql([JsNode.SCRIPT,[JsNode.SCRIPTBODY,[JsNode.VARSTMT,["var",JsNode.VARDECL,[JsNode.ARRBINDPAT,["[",JsNode.SINGLENAME,[JsNode.BINDID,["x"]],",",JsNode.BINDELEM,[JsNode.OBJBINDPAT,["{",JsNode.BINDPROPT,[JsNode.PROPTNAME,[JsNode.LTRPROPT,["\"a\""]],":",JsNode.BINDELEM,[JsNode.ARRBINDPAT,["[",JsNode.SINGLENAME,[JsNode.BINDID,["y"],JsNode.INITLZ,["=",JsNode.PRMREXPR,["1"]]],",",JsNode.BINDELEM,[JsNode.OBJBINDPAT,["{",JsNode.BINDPROPT,[JsNode.SINGLENAME,[JsNode.BINDID,["z"],JsNode.INITLZ,["=",JsNode.PRMREXPR,["2"]]]],"}"]],",",JsNode.BINDREST,["...",JsNode.BINDID,["o"]],"]"]]],"}"]],"]"],JsNode.INITLZ,["=",JsNode.PRMREXPR,[JsNode.ARRLTR,["[","]"]]]]]]]]); | ||
}); | ||
it('destructuring without assign should throw error', function() { | ||
var parser = homunculus.getParser('es6'); | ||
expect(function() { | ||
parser.parse('var [a];'); | ||
}).to.throwError(); | ||
}); | ||
it('destructuring object error 1', function() { | ||
var parser = homunculus.getParser('es6'); | ||
expect(function() { | ||
parser.parse('var {'); | ||
}).to.throwError(); | ||
}); | ||
it('destructuring object error 2', function() { | ||
var parser = homunculus.getParser('es6'); | ||
expect(function() { | ||
parser.parse('var {a'); | ||
}).to.throwError(); | ||
}); | ||
it('destructuring object error 3', function() { | ||
var parser = homunculus.getParser('es6'); | ||
expect(function() { | ||
parser.parse('var {!'); | ||
}).to.throwError(); | ||
}); | ||
it('destructuring object error 4', function() { | ||
var parser = homunculus.getParser('es6'); | ||
expect(function() { | ||
parser.parse('var {a '); | ||
}).to.throwError(); | ||
}); | ||
it('letdecl 1', function() { | ||
var parser = homunculus.getParser('es6'); | ||
var node = parser.parse('let a'); | ||
expect(tree(node)).to.eql([JsNode.SCRIPT,[JsNode.SCRIPTBODY,[JsNode.LEXDECL,["let",JsNode.LEXBIND,[JsNode.BINDID,["a"]]]]]]); | ||
}); | ||
it('letdecl 2', function() { | ||
var parser = homunculus.getParser('es6'); | ||
var node = parser.parse('let a, b = 1'); | ||
expect(tree(node)).to.eql([JsNode.SCRIPT,[JsNode.SCRIPTBODY,[JsNode.LEXDECL,["let",JsNode.LEXBIND,[JsNode.BINDID,["a"]],",",JsNode.LEXBIND,[JsNode.BINDID,["b"],JsNode.INITLZ,["=",JsNode.PRMREXPR,["1"]]]]]]]); | ||
}); | ||
it('cstdecl 1', function() { | ||
var parser = homunculus.getParser('es6'); | ||
var node = parser.parse('const a'); | ||
expect(tree(node)).to.eql([JsNode.SCRIPT,[JsNode.SCRIPTBODY,[JsNode.LEXDECL,["const",JsNode.LEXBIND,[JsNode.BINDID,["a"]]]]]]); | ||
}); | ||
it('cstdecl 2', function() { | ||
var parser = homunculus.getParser('es6'); | ||
var node = parser.parse('const a, b = 1'); | ||
expect(tree(node)).to.eql([JsNode.SCRIPT,[JsNode.SCRIPTBODY,[JsNode.LEXDECL,["const",JsNode.LEXBIND,[JsNode.BINDID,["a"]],",",JsNode.LEXBIND,[JsNode.BINDID,["b"],JsNode.INITLZ,["=",JsNode.PRMREXPR,["1"]]]]]]]); | ||
}); | ||
it('fndecl', function() { | ||
var parser = homunculus.getParser('es6'); | ||
var node = parser.parse('function a() {}'); | ||
expect(tree(node)).to.eql([JsNode.SCRIPT,[JsNode.SCRIPTBODY,[JsNode.FNDECL,["function",JsNode.BINDID,["a"],"(",JsNode.FMPARAMS,[],")","{",JsNode.FNBODY,[],"}"]]]]); | ||
}); | ||
it('fndecl with params', function() { | ||
var parser = homunculus.getParser('es6'); | ||
var node = parser.parse('function a(b,c) {}'); | ||
expect(tree(node)).to.eql([JsNode.SCRIPT,[JsNode.SCRIPTBODY,[JsNode.FNDECL,["function",JsNode.BINDID,["a"],"(",JsNode.FMPARAMS,[JsNode.SINGLENAME,[JsNode.BINDID,["b"]],",",JsNode.SINGLENAME,[JsNode.BINDID,["c"]]],")","{",JsNode.FNBODY,[],"}"]]]]); | ||
}); | ||
it('fndecl bindelem', function() { | ||
var parser = homunculus.getParser('es6'); | ||
var node = parser.parse('function a(b, c = 1, ...d){}'); | ||
expect(tree(node)).to.eql([JsNode.SCRIPT,[JsNode.SCRIPTBODY,[JsNode.FNDECL,["function",JsNode.BINDID,["a"],"(",JsNode.FMPARAMS,[JsNode.SINGLENAME,[JsNode.BINDID,["b"]],",",JsNode.SINGLENAME,[JsNode.BINDID,["c"],JsNode.INITLZ,["=",JsNode.PRMREXPR,["1"]]],",",JsNode.BINDREST,["...",JsNode.BINDID,["d"]]],")","{",JsNode.FNBODY,[],"}"]]]]); | ||
}); | ||
it('fndecl bindelem 2', function() { | ||
var parser = homunculus.getParser('es6'); | ||
var node = parser.parse('function a(b, c = d*2){}'); | ||
expect(tree(node)).to.eql([JsNode.SCRIPT,[JsNode.SCRIPTBODY,[JsNode.FNDECL,["function",JsNode.BINDID,["a"],"(",JsNode.FMPARAMS,[JsNode.SINGLENAME,[JsNode.BINDID,["b"]],",",JsNode.SINGLENAME,[JsNode.BINDID,["c"],JsNode.INITLZ,["=",JsNode.MTPLEXPR,[JsNode.PRMREXPR,["d"],"*",JsNode.PRMREXPR,["2"]]]]],")","{",JsNode.FNBODY,[],"}"]]]]); | ||
}); | ||
it('fndecl with fnbody', function() { | ||
var parser = homunculus.getParser('es6'); | ||
var node = parser.parse('function a() {;}'); | ||
expect(tree(node)).to.eql([JsNode.SCRIPT,[JsNode.SCRIPTBODY,[JsNode.FNDECL,["function",JsNode.BINDID,["a"],"(",JsNode.FMPARAMS,[],")","{",JsNode.FNBODY,[JsNode.EMPTSTMT,[";"]],"}"]]]]); | ||
}); | ||
it('fndecl rest', function() { | ||
var parser = homunculus.getParser('es6'); | ||
var node = parser.parse('function a(...b){}'); | ||
expect(tree(node)).to.eql([JsNode.SCRIPT,[JsNode.SCRIPTBODY,[JsNode.FNDECL,["function",JsNode.BINDID,["a"],"(",JsNode.FMPARAMS,[JsNode.BINDREST,["...",JsNode.BINDID,["b"]]],")","{",JsNode.FNBODY,[],"}"]]]]); | ||
}); | ||
it('fndecl error 1', function() { | ||
var parser = homunculus.getParser('es6'); | ||
expect(function() { | ||
parser.parse('function'); | ||
}).to.throwError(); | ||
}); | ||
it('fndecl error 2', function() { | ||
var parser = homunculus.getParser('es6'); | ||
expect(function() { | ||
parser.parse('function a'); | ||
}).to.throwError(); | ||
}); | ||
it('fndecl error 3', function() { | ||
var parser = homunculus.getParser('es6'); | ||
expect(function() { | ||
parser.parse('function a('); | ||
}).to.throwError(); | ||
}); | ||
it('fndecl error 4', function() { | ||
var parser = homunculus.getParser('es6'); | ||
expect(function() { | ||
parser.parse('function a()'); | ||
}).to.throwError(); | ||
}); | ||
it('fndecl error 5', function() { | ||
var parser = homunculus.getParser('es6'); | ||
expect(function() { | ||
parser.parse('function a() {'); | ||
}).to.throwError(); | ||
}); | ||
it('fnexpr 1', function() { | ||
var parser = homunculus.getParser('es6'); | ||
var node = parser.parse('~function() {}()'); | ||
expect(tree(node)).to.eql([JsNode.SCRIPT,[JsNode.SCRIPTBODY,[JsNode.EXPRSTMT,[JsNode.UNARYEXPR,["~",JsNode.CALLEXPR,[JsNode.FNEXPR,["function","(",JsNode.FMPARAMS,[],")","{",JsNode.FNBODY,[],"}"],JsNode.ARGS,["(",")"]]]]]]]); | ||
}); | ||
it('fnexpr 2', function() { | ||
var parser = homunculus.getParser('es6'); | ||
var node = parser.parse('(function a() {})()'); | ||
expect(tree(node)).to.eql([JsNode.SCRIPT,[JsNode.SCRIPTBODY,[JsNode.EXPRSTMT,[JsNode.CALLEXPR,[JsNode.PRMREXPR,["(",JsNode.FNEXPR,["function",JsNode.BINDID,["a"],"(",JsNode.FMPARAMS,[],")","{",JsNode.FNBODY,[],"}"],")"],JsNode.ARGS,["(",")"]]]]]]); | ||
}); | ||
it('fnexpr error 1', function() { | ||
var parser = homunculus.getParser('es6'); | ||
expect(function() { | ||
parser.parse('(function'); | ||
}).to.throwError(); | ||
}); | ||
it('fnexpr error 2', function() { | ||
var parser = homunculus.getParser('es6'); | ||
expect(function() { | ||
parser.parse('(function('); | ||
}).to.throwError(); | ||
}); | ||
it('fnexpr error 3', function() { | ||
var parser = homunculus.getParser('es6'); | ||
expect(function() { | ||
parser.parse('(function(a,'); | ||
}).to.throwError(); | ||
}); | ||
it('fnexpr error 4', function() { | ||
var parser = homunculus.getParser('es6'); | ||
expect(function() { | ||
parser.parse('(function(a,1'); | ||
}).to.throwError(); | ||
}); | ||
it('arrinit error', function() { | ||
var parser = homunculus.getParser('es6'); | ||
expect(function() { | ||
parser.parse('['); | ||
}).to.throwError(); | ||
}); | ||
it('arrltr', function() { | ||
var parser = homunculus.getParser('es6'); | ||
var node = parser.parse('[,,,2,3,]'); | ||
expect(tree(node)).to.eql([JsNode.SCRIPT,[JsNode.SCRIPTBODY,[JsNode.EXPRSTMT,[JsNode.PRMREXPR,[JsNode.ARRLTR,["[",",",",",",",JsNode.PRMREXPR,["2"],",",JsNode.PRMREXPR,["3"],",","]"]]]]]]); | ||
}); | ||
it('arrltr spread', function() { | ||
var parser = homunculus.getParser('es6'); | ||
var node = parser.parse('[...a]'); | ||
expect(tree(node)).to.eql([JsNode.SCRIPT,[JsNode.SCRIPTBODY,[JsNode.EXPRSTMT,[JsNode.PRMREXPR,[JsNode.ARRLTR,["[",JsNode.SPREAD,["...",JsNode.PRMREXPR,["a"]],"]"]]]]]]); | ||
}); | ||
it('arrltr error', function() { | ||
var parser = homunculus.getParser('es6'); | ||
expect(function() { | ||
parser.parse('[,,,2,3,'); | ||
}).to.throwError(); | ||
}); | ||
it('arrcmph no if', function() { | ||
var parser = homunculus.getParser('es6'); | ||
var node = parser.parse('[for(a of b)a]'); | ||
expect(tree(node)).to.eql([JsNode.SCRIPT,[JsNode.SCRIPTBODY,[JsNode.EXPRSTMT,[JsNode.PRMREXPR,[JsNode.ARRCMPH,["[",JsNode.CMPHFOR,["for","(",JsNode.BINDID,["a"],"of",JsNode.PRMREXPR,["b"],")"],JsNode.PRMREXPR,["a"],"]"]]]]]]); | ||
}); | ||
it('arrcmph with if', function() { | ||
var parser = homunculus.getParser('es6'); | ||
var node = parser.parse('[for(a of b)if(a>1)a]'); | ||
expect(tree(node)).to.eql([JsNode.SCRIPT,[JsNode.SCRIPTBODY,[JsNode.EXPRSTMT,[JsNode.PRMREXPR,[JsNode.ARRCMPH,["[",JsNode.CMPHFOR,["for","(",JsNode.BINDID,["a"],"of",JsNode.PRMREXPR,["b"],")"],JsNode.CMPHIF,["if","(",JsNode.RELTEXPR,[JsNode.PRMREXPR,["a"],">",JsNode.PRMREXPR,["1"]],")"],JsNode.PRMREXPR,["a"],"]"]]]]]]); | ||
}); | ||
it('arrcmph recursion', function() { | ||
var parser = homunculus.getParser('es6'); | ||
var node = parser.parse('[for(a of b)if(true)for(c of a)if(false)c]'); | ||
expect(tree(node)).to.eql([JsNode.SCRIPT,[JsNode.SCRIPTBODY,[JsNode.EXPRSTMT,[JsNode.PRMREXPR,[JsNode.ARRCMPH,["[",JsNode.CMPHFOR,["for","(",JsNode.BINDID,["a"],"of",JsNode.PRMREXPR,["b"],")"],JsNode.CMPHIF,["if","(",JsNode.PRMREXPR,["true"],")"],JsNode.CMPHFOR,["for","(",JsNode.BINDID,["c"],"of",JsNode.PRMREXPR,["a"],")"],JsNode.CMPHIF,["if","(",JsNode.PRMREXPR,["false"],")"],JsNode.PRMREXPR,["c"],"]"]]]]]]); | ||
}); | ||
it('arrcmph forbindpat', function() { | ||
var parser = homunculus.getParser('es6'); | ||
var node = parser.parse('[for([a,b] of c)a+b]'); | ||
expect(tree(node)).to.eql([JsNode.SCRIPT,[JsNode.SCRIPTBODY,[JsNode.EXPRSTMT,[JsNode.PRMREXPR,[JsNode.ARRCMPH,["[",JsNode.CMPHFOR,["for","(",JsNode.ARRBINDPAT,["[",JsNode.SINGLENAME,[JsNode.BINDID,["a"]],",",JsNode.SINGLENAME,[JsNode.BINDID,["b"]],"]"],"of",JsNode.PRMREXPR,["c"],")"],JsNode.ADDEXPR,[JsNode.PRMREXPR,["a"],"+",JsNode.PRMREXPR,["b"]],"]"]]]]]]); | ||
}); | ||
it('arrcmph error 1', function() { | ||
var parser = homunculus.getParser('es6'); | ||
expect(function() { | ||
parser.parse('[for'); | ||
}).to.throwError(); | ||
}); | ||
it('arrcmph error 2', function() { | ||
var parser = homunculus.getParser('es6'); | ||
expect(function() { | ||
parser.parse('[for('); | ||
}).to.throwError(); | ||
}); | ||
it('arrcmph error 3', function() { | ||
var parser = homunculus.getParser('es6'); | ||
expect(function() { | ||
parser.parse('[for(a'); | ||
}).to.throwError(); | ||
}); | ||
it('arrcmph error 4', function() { | ||
var parser = homunculus.getParser('es6'); | ||
expect(function() { | ||
parser.parse('[for(a of'); | ||
}).to.throwError(); | ||
}); | ||
it('arrcmph error 5', function() { | ||
var parser = homunculus.getParser('es6'); | ||
expect(function() { | ||
parser.parse('[for(a of b'); | ||
}).to.throwError(); | ||
}); | ||
it('arrcmph error 6', function() { | ||
var parser = homunculus.getParser('es6'); | ||
expect(function() { | ||
parser.parse('[for(a of b)'); | ||
}).to.throwError(); | ||
}); | ||
it('arrcmph error 7', function() { | ||
var parser = homunculus.getParser('es6'); | ||
expect(function() { | ||
parser.parse('[for(a of b)if'); | ||
}).to.throwError(); | ||
}); | ||
it('arrcmph error 8', function() { | ||
var parser = homunculus.getParser('es6'); | ||
expect(function() { | ||
parser.parse('[for(a of b)if('); | ||
}).to.throwError(); | ||
}); | ||
it('arrcmph error 9', function() { | ||
var parser = homunculus.getParser('es6'); | ||
expect(function() { | ||
parser.parse('[for(a of b)if(true'); | ||
}).to.throwError(); | ||
}); | ||
it('arrcmph error 10', function() { | ||
var parser = homunculus.getParser('es6'); | ||
expect(function() { | ||
parser.parse('[for(a of b)if(true)'); | ||
}).to.throwError(); | ||
}); | ||
it('arrcmph error 11', function() { | ||
var parser = homunculus.getParser('es6'); | ||
expect(function() { | ||
parser.parse('[for(a of b)if(true)a'); | ||
}).to.throwError(); | ||
}); | ||
}); | ||
}); |
@@ -462,2 +462,8 @@ var homunculus = require('../'); | ||
}); | ||
it('assignexpr error', function() { | ||
var parser = homunculus.getParser('js'); | ||
expect(function() { | ||
parser.parse('a + b = c'); | ||
}).to.throwError(); | ||
}); | ||
it('expr 1', function() { | ||
@@ -464,0 +470,0 @@ var parser = homunculus.getParser('js'); |
@@ -67,10 +67,8 @@ define(function(require, exports, module) { | ||
}).statics({ | ||
PROGRAM: 'program', | ||
ELEMS: 'elems', | ||
ELEM: 'elem', | ||
CSTSTMT: 'cststmt', | ||
LETSTMT: 'letstmt', | ||
SCRIPT: 'script', | ||
SCRIPTBODY: 'scriptbody', | ||
VARSTMT: 'varstmt', | ||
VARDECL: 'vardecl', | ||
FNBODY: 'fnbody', | ||
BLOCKSTMT: 'blockstmt', | ||
BLOCK: 'block', | ||
@@ -110,2 +108,3 @@ ITERSTMT: 'iterstmt', | ||
CACH: 'cach', | ||
CACHPARAM: 'cachparam', | ||
FINL: 'finl', | ||
@@ -132,3 +131,2 @@ FNDECL: 'fndecl', | ||
PROPTASSIGN: 'proptassign', | ||
PROPTNAME: 'proptname', | ||
PROPTSETS: 'propsets', | ||
@@ -141,12 +139,21 @@ ARGS: 'args', | ||
CALLEXPR: 'callexpr', | ||
SPREAD: 'spread', | ||
ARRCMPH: 'arrcmph', | ||
CMPHFOR: 'cmphfor', | ||
INITLZ: 'initlz', | ||
BINDID: 'bindid', | ||
ARRBINDPAT: 'arrbindpat', | ||
OBJBINDPAT: 'objbindpat', | ||
BINDPROPT: 'bindpropt', | ||
SINGLENAME: 'singlename', | ||
BINDELEM: 'bindelem', | ||
BINDREST: 'bindrest', | ||
BINDID: 'bindid', | ||
SPREAD: 'spread', | ||
ARRCMPH: 'arrcmph', | ||
CMPHFOR: 'cmphfor', | ||
PROPTNAME: 'proptname', | ||
SINGLENAME: 'singlename', | ||
BINDPROPT: 'bindpropt', | ||
LTRPROPT: 'ltrpropt', | ||
CMPTPROPT: 'cmptpropt', | ||
LEXDECL: 'lexdecl', | ||
LEXBIND: 'lexbind', | ||
FMPARAMS: 'fmparams', | ||
CMPHIF: 'cmphif', | ||
getKey: function(s) { | ||
@@ -153,0 +160,0 @@ if(!s) { |
@@ -10,2 +10,17 @@ define(function(require, exports, module) { | ||
S[Token.BLANK] = S[Token.TAB] = S[Token.COMMENT] = S[Token.LINE] = S[Token.ENTER] = true; | ||
var NOASSIGN = {}; | ||
NOASSIGN[Node.CNDTEXPR] | ||
= NOASSIGN[Node.LOGOREXPR] | ||
= NOASSIGN[Node.LOGANDEXPR] | ||
= NOASSIGN[Node.BITOREXPR] | ||
= NOASSIGN[Node.BITXOREXPR] | ||
= NOASSIGN[Node.BITANDEXPR] | ||
= NOASSIGN[Node.EQEXPR] | ||
= NOASSIGN[Node.RELTEXPR] | ||
= NOASSIGN[Node.SHIFTEXPR] | ||
= NOASSIGN[Node.ADDEXPR] | ||
= NOASSIGN[Node.MTPLEXPR] | ||
= NOASSIGN[Node.UNARYEXPR] | ||
= NOASSIGN[Node.POSTFIXEXPR] | ||
= true; | ||
var Parser = Class(function(lexer) { | ||
@@ -16,3 +31,3 @@ this.init(lexer); | ||
this.lexer.parse(code); | ||
this.tree = this.program(); | ||
this.tree = this.script(); | ||
return this.tree; | ||
@@ -45,3 +60,3 @@ }, | ||
}, | ||
program: function() { | ||
script: function() { | ||
this.tokens = this.lexer.tokens(); | ||
@@ -52,20 +67,24 @@ this.length = this.tokens.length; | ||
} | ||
var node = new Node(Node.PROGRAM); | ||
var node = new Node(Node.SCRIPT); | ||
if(this.look) { | ||
node.add(this.scriptbody()); | ||
} | ||
return node; | ||
}, | ||
scriptbody: function() { | ||
var node = new Node(Node.SCRIPTBODY); | ||
while(this.look) { | ||
node.add(this.element()); | ||
node.add(this.stmtlitem()); | ||
} | ||
return node; | ||
}, | ||
element: function(allowSuper) { | ||
if(this.look.content() == 'function') { | ||
return this.fndecl(); | ||
stmtlitem: function() { | ||
if(['function', 'class', 'let', 'const'].indexOf(this.look.content()) > -1) { | ||
return this.decl(); | ||
} | ||
else if(this.look.content() == 'class') { | ||
return this.classdecl(); | ||
} | ||
else { | ||
return this.stmt(allowSuper); | ||
return this.stmt(); | ||
} | ||
}, | ||
stmt: function(allowSuper) { | ||
decl: function() { | ||
if(!this.look) { | ||
@@ -76,9 +95,19 @@ this.error(); | ||
case 'let': | ||
return this.letstmt(); | ||
case 'const': | ||
return this.cststmt(); | ||
return this.lexdecl(); | ||
case 'function': | ||
return this.fndecl(); | ||
case 'class': | ||
return this.classdecl(); | ||
} | ||
}, | ||
stmt: function() { | ||
if(!this.look) { | ||
this.error(); | ||
} | ||
switch(this.look.content()) { | ||
case 'var': | ||
return this.varstmt(); | ||
case '{': | ||
return this.block(); | ||
return this.blockstmt(); | ||
case ';': | ||
@@ -108,9 +137,11 @@ return this.emptstmt(); | ||
return this.debstmt(); | ||
case 'super': | ||
if(!allowSuper) { | ||
this.error('super must in a class'); | ||
} | ||
return this.superstmt(); | ||
case 'import': | ||
return this.imptstmt(); | ||
case 'yield': | ||
return this.labstmt(); | ||
// case 'super': | ||
// if(!allowSuper) { | ||
// this.error('super must in a class'); | ||
// } | ||
// return this.superstmt(); | ||
// case 'import': | ||
// return this.imptstmt(); | ||
default: | ||
@@ -138,35 +169,44 @@ if(this.look.type() == Token.ID) { | ||
}, | ||
cststmt: function(noSem) { | ||
var node = new Node(Node.CSTSTMT); | ||
node.add( | ||
this.match('const'), | ||
this.vardecl() | ||
); | ||
lexdecl: function() { | ||
var node = new Node(Node.LEXDECL); | ||
if(this.look.content() == 'let') { | ||
node.add(this.match()); | ||
} | ||
else if(this.look.content() == 'const') { | ||
node.add(this.match()); | ||
} | ||
else { | ||
this.error(); | ||
} | ||
node.add(this.lexbind()); | ||
while(this.look && this.look.content() == ',') { | ||
node.add( | ||
this.match(), | ||
this.vardecl() | ||
this.lexbind() | ||
); | ||
} | ||
if(!noSem) { | ||
node.add(this.match(';')); | ||
} | ||
return node; | ||
}, | ||
letstmt: function(noSem) { | ||
var node = new Node(Node.LETSTMT); | ||
node.add( | ||
this.match('let'), | ||
this.vardecl() | ||
); | ||
while(this.look && this.look.content() == ',') { | ||
node.add( | ||
this.match(), | ||
this.vardecl() | ||
); | ||
lexbind: function() { | ||
var node = new Node(Node.LEXBIND); | ||
this.declnode(node); | ||
return node; | ||
}, | ||
declnode: function(node) { | ||
if(!this.look) { | ||
this.error('missing variable name'); | ||
} | ||
if(!noSem) { | ||
node.add(this.match(';')); | ||
if(['[', '{'].indexOf(this.look.content()) > -1) { | ||
node.add(this.bindpat()); | ||
if(!this.look || this.look.content() != '=') { | ||
this.error('missing = in destructuring declaration'); | ||
} | ||
node.add(this.initlz()); | ||
} | ||
return node; | ||
else { | ||
node.add(this.bindid('missing variable name')); | ||
if(this.look && this.look.content() == '=') { | ||
node.add(this.initlz()); | ||
} | ||
} | ||
}, | ||
@@ -192,20 +232,10 @@ varstmt: function(noSem) { | ||
var node = new Node(Node.VARDECL); | ||
if(!this.look) { | ||
this.error('missing variable name'); | ||
} | ||
if(['[', '{'].indexOf(this.look.content()) > -1) { | ||
node.add(this.bindpat()); | ||
if(!this.look || this.look.content() != '=') { | ||
this.error('missing = in destructuring declaration'); | ||
} | ||
node.add(this.assign()); | ||
} | ||
else { | ||
node.add(this.match(Token.ID, 'missing variable name')); | ||
if(this.look && this.look.content() == '=') { | ||
node.add(this.assign()); | ||
} | ||
} | ||
this.declnode(node); | ||
return node; | ||
}, | ||
bindid: function(msg) { | ||
var node = new Node(Node.BINDID); | ||
node.add(this.match(Token.ID, msg)); | ||
return node; | ||
}, | ||
bindpat: function() { | ||
@@ -218,2 +248,5 @@ if(this.look.content() == '[') { | ||
} | ||
else { | ||
this.error(); | ||
} | ||
}, | ||
@@ -235,3 +268,3 @@ arrbindpat: function() { | ||
if(this.look.content() == '...') { | ||
node.add(this.restparam()); | ||
node.add(this.bindrest()); | ||
} | ||
@@ -246,3 +279,3 @@ node.add(this.match(']', 'missing ] after element list')); | ||
if(this.look && this.look.content() == '=') { | ||
node.add(this.assign()); | ||
node.add(this.initlz()); | ||
} | ||
@@ -257,8 +290,16 @@ } | ||
var node = new Node(Node.SINGLENAME); | ||
node.add(this.match(Token.ID)); | ||
node.add(this.bindid()); | ||
if(this.look && this.look.content() == '=') { | ||
node.add(this.assign()); | ||
node.add(this.initlz()); | ||
} | ||
return node; | ||
}, | ||
bindrest: function() { | ||
var node = new Node(Node.BINDREST); | ||
node.add( | ||
this.match('...'), | ||
this.bindid('no parameter name after ...') | ||
); | ||
return node; | ||
}, | ||
objbindpat: function() { | ||
@@ -278,2 +319,3 @@ var node = new Node(Node.OBJBINDPAT); | ||
var node = new Node(Node.BINDPROPT); | ||
//只能是singlename或者properyname | ||
switch(this.look.type()) { | ||
@@ -285,6 +327,17 @@ case Token.ID: | ||
default: | ||
this.error('invalid property id'); | ||
if(this.look.content() != '[') { | ||
this.error('invalid property id'); | ||
} | ||
} | ||
//[为PropertyName左推导 | ||
if(this.look.content() == '[') { | ||
node.add( | ||
this.proptname(), | ||
this.match(':'), | ||
this.bindelem() | ||
); | ||
return node; | ||
} | ||
//根据LL2分辨是PropertyName[?Yield, ?GeneratorParameter] : BindingElement[?Yield, ?GeneratorParameter] | ||
//还是SingleNameBinding [?Yield, ?GeneratorParameter] | ||
//还是SingleNameBinding[?Yield, ?GeneratorParameter] | ||
for(var i = this.index; i < this.length; i++) { | ||
@@ -294,4 +347,7 @@ var next = this.tokens[i]; | ||
if(next.content() == ':') { | ||
node.add(this.match(), this.match()); | ||
node.add(this.bindelem()); | ||
node.add( | ||
this.proptname(), | ||
this.match(':'), | ||
this.bindelem() | ||
); | ||
} | ||
@@ -315,7 +371,12 @@ else { | ||
}, | ||
block: function() { | ||
blockstmt: function() { | ||
var node = new Node(Node.BLOCKSTMT); | ||
node.add(this.block()); | ||
return node; | ||
}, | ||
block: function(msg) { | ||
var node = new Node(Node.BLOCK); | ||
node.add(this.match('{')); | ||
node.add(this.match('{', msg)); | ||
while(this.look && this.look.content() != '}') { | ||
node.add(this.stmt()); | ||
node.add(this.stmtlitem()); | ||
} | ||
@@ -499,6 +560,6 @@ node.add(this.match('}', 'missing } in compound statement')); | ||
node.add( | ||
this.match('with'), | ||
this.match('with', 'missing ( before with-statement object'), | ||
this.match('('), | ||
this.expr(), | ||
this.match(')'), | ||
this.match(')', 'missing ) after with-statement object'), | ||
this.stmt() | ||
@@ -564,4 +625,9 @@ ); | ||
var node = new Node(Node.LABSTMT); | ||
if(this.look.content() == 'yield') { | ||
node.add(this.match()); | ||
} | ||
else { | ||
node.add(this.match(Token.ID)); | ||
} | ||
node.add( | ||
this.match(Token.ID), | ||
this.match(':'), | ||
@@ -585,3 +651,3 @@ this.stmt() | ||
this.match('try'), | ||
this.block() | ||
this.block('missing { before try block') | ||
); | ||
@@ -607,10 +673,20 @@ if(this.look && this.look.content() == 'catch') { | ||
node.add( | ||
this.match('catch'), | ||
this.match('('), | ||
this.match(Token.ID, 'missing identifier in catch'), | ||
this.match(')'), | ||
this.block() | ||
this.match('catch', 'missing catch or finally after try'), | ||
this.match('(', 'missing ( before catch'), | ||
this.cachparam(), | ||
this.match(')', 'missing ) after catch'), | ||
this.block('missing { before catch block') | ||
); | ||
return node; | ||
}, | ||
cachparam: function() { | ||
var node = new Node(Node.CACHPARAM); | ||
if(['[', '{'].indexOf(this.look.content()) > -1) { | ||
node.add(this.bindpat()); | ||
} | ||
else { | ||
node.add(this.bindid('missing identifier in catch')); | ||
} | ||
return node; | ||
}, | ||
finl: function() { | ||
@@ -620,3 +696,3 @@ var node = new Node(Node.FINL); | ||
this.match('finally'), | ||
this.block() | ||
this.block('missing { before finally block') | ||
); | ||
@@ -665,16 +741,9 @@ return node; | ||
this.match('function'), | ||
this.match(Token.ID, 'function statement requires a name'), | ||
this.match('(') | ||
); | ||
if(!this.look) { | ||
this.error('missing formal parameter'); | ||
} | ||
if(this.look.content() != ')') { | ||
node.add(this.fnparams()); | ||
} | ||
node.add( | ||
this.match(')'), | ||
this.bindid('function statement requires a name'), | ||
this.match('(', 'missing ( before formal parameters'), | ||
this.fmparams(), | ||
this.match(')', 'missing ) after formal parameters'), | ||
this.match('{'), | ||
this.fnbody(), | ||
this.match('}') | ||
this.match('}', 'missing } after function body') | ||
); | ||
@@ -685,3 +754,5 @@ return node; | ||
var node = new Node(Node.FNEXPR); | ||
node.add(this.match('function')); | ||
node.add( | ||
this.match('function') | ||
); | ||
if(!this.look) { | ||
@@ -691,33 +762,28 @@ this.error('missing formal parameter'); | ||
if(this.look.type() == Token.ID) { | ||
node.add(this.match()); | ||
node.add(this.bindid()); | ||
} | ||
node.add(this.match('(')); | ||
if(!this.look) { | ||
this.error(); | ||
} | ||
if(this.look.content() != ')') { | ||
node.add(this.fnparams()); | ||
} | ||
node.add( | ||
this.match(')'), | ||
this.match('(', 'missing ( before formal parameters'), | ||
this.fmparams(), | ||
this.match(')', 'missing ) after formal parameters'), | ||
this.match('{'), | ||
this.fnbody(), | ||
this.match('}', 'missing } in compound statement') | ||
this.match('}', 'missing } after function body') | ||
); | ||
return node; | ||
}, | ||
fnparams: function() { | ||
var node = new Node(Node.FNPARAMS); | ||
while(this.look && this.look.content() != ')' && this.look.content() != '...') { | ||
node.add(this.match(Token.ID, 'missing formal parameter')); | ||
if(this.look) { | ||
if(this.look.content() == ',') { | ||
fmparams: function() { | ||
var node = new Node(Node.FMPARAMS); | ||
if(!this.look) { | ||
this.error('missing formal parameter'); | ||
} | ||
while(this.look && this.look.content() != ')') { | ||
if(this.look.content() == '...') { | ||
break; | ||
} | ||
else { | ||
node.add(this.bindelem()); | ||
if(this.look && this.look.content() == ',') { | ||
node.add(this.match()); | ||
} | ||
else if(this.look.content() == '=') { | ||
node.add(this.bindelement()); | ||
if(this.look && this.look.content() == ',') { | ||
node.add(this.match()); | ||
} | ||
} | ||
} | ||
@@ -729,20 +795,10 @@ } | ||
if(this.look.content() == '...') { | ||
node.add(this.restparam()); | ||
node.add(this.bindrest()); | ||
} | ||
return node; | ||
}, | ||
bindelement: function() { | ||
var node = new Node(Node.BINDELEMENT); | ||
node.add(this.match('='), this.assignexpr()); | ||
return node; | ||
}, | ||
restparam: function() { | ||
var node = new Node(Node.RESTPARAM); | ||
node.add(this.match('...'), this.match(Token.ID)); | ||
return node; | ||
}, | ||
fnbody: function(allowSuper) { | ||
fnbody: function() { | ||
var node = new Node(Node.FNBODY); | ||
while(this.look && this.look.content() != '}') { | ||
node.add(this.element(allowSuper)); | ||
node.add(this.stmtlitem()); | ||
} | ||
@@ -835,5 +891,13 @@ return node; | ||
}, | ||
initlz: function(noIn) { | ||
var node = new Node(Node.INITLZ); | ||
node.add( | ||
this.match('='), | ||
this.assignexpr(noIn) | ||
); | ||
return node; | ||
}, | ||
assignexpr: function(noIn) { | ||
var node = new Node(Node.ASSIGNEXPR), | ||
cndt = this.cndtexpr(noIn); | ||
var node = new Node(Node.ASSIGNEXPR); | ||
var cndt = this.cndtexpr(noIn); | ||
if(this.look && { | ||
@@ -852,3 +916,3 @@ '*=': true, | ||
'=': true | ||
}.hasOwnProperty(this.look.content())) { | ||
}.hasOwnProperty(this.look.content()) && !NOASSIGN.hasOwnProperty(cndt.name())) { | ||
node.add(cndt, this.match(), this.assignexpr(noIn)); | ||
@@ -1140,3 +1204,3 @@ } | ||
this.match(), | ||
this.match(Token.ID) | ||
this.match(Token.ID, 'missing name after . operator') | ||
); | ||
@@ -1176,3 +1240,3 @@ } | ||
this.match(), | ||
this.match(Token.ID) | ||
this.match(Token.ID, 'missing name after . operator') | ||
); | ||
@@ -1216,3 +1280,3 @@ } | ||
this.match(), | ||
this.match(Token.ID) | ||
this.match(Token.ID, 'missing name after . operator') | ||
); | ||
@@ -1270,7 +1334,2 @@ } | ||
}, | ||
bindid: function() { | ||
var node = new Node(Node.BINDID); | ||
node.add(this.match('...'), this.assignexpr()); | ||
return node; | ||
}, | ||
arrinit: function() { | ||
@@ -1296,2 +1355,14 @@ //根据LL2分辨是arrltr还是arrcmph | ||
node.add(this.cmphfor()); | ||
while(this.look && this.look.content() != ']') { | ||
if(this.look.content() == 'for') { | ||
node.add(this.cmphfor()); | ||
} | ||
else if(this.look.content() == 'if') { | ||
node.add(this.cmphif()); | ||
} | ||
else { | ||
node.add(this.assignexpr()); | ||
break; | ||
} | ||
} | ||
node.add(this.match(']', 'missing ] after element list')); | ||
@@ -1302,5 +1373,33 @@ return node; | ||
var node = new Node(Node.CMPHFOR); | ||
node.add(this.match('for')); | ||
node.add( | ||
this.match('for'), | ||
this.match('('), | ||
this.forbind(), | ||
this.match('of'), | ||
this.assignexpr(), | ||
this.match(')') | ||
); | ||
return node; | ||
}, | ||
forbind: function() { | ||
if(!this.look) { | ||
this.error(); | ||
} | ||
if(['[', '{'].indexOf(this.look.content()) > -1) { | ||
return this.bindpat(); | ||
} | ||
else { | ||
return this.bindid(); | ||
} | ||
}, | ||
cmphif: function() { | ||
var node = new Node(Node.CMPHIF); | ||
node.add( | ||
this.match('if'), | ||
this.match('('), | ||
this.assignexpr(), | ||
this.match(')') | ||
); | ||
return node; | ||
}, | ||
arrltr: function() { | ||
@@ -1416,15 +1515,34 @@ var node = new Node(Node.ARRLTR); | ||
var node = new Node(Node.PROPTNAME); | ||
if(this.look) { | ||
switch(this.look.type()) { | ||
case Token.ID: | ||
case Token.NUMBER: | ||
case Token.STRING: | ||
node.add(this.match()); | ||
break; | ||
default: | ||
this.error('missing name after . operator'); | ||
} | ||
if(!this.look) { | ||
this.error('invalid property id'); | ||
} | ||
if(this.look.content() == '[') { | ||
node.add(this.cmptpropt()); | ||
} | ||
else { | ||
node.add(this.ltrpropt()); | ||
} | ||
return node; | ||
}, | ||
ltrpropt: function() { | ||
var node = new Node(Node.LTRPROPT); | ||
switch(this.look.type()) { | ||
case Token.ID: | ||
case Token.NUMBER: | ||
case Token.STRING: | ||
node.add(this.match()); | ||
return node; | ||
default: | ||
this.error('invalid property id'); | ||
} | ||
}, | ||
cmptpropt: function() { | ||
var node = new Node(Node.CMPTPROPT); | ||
node.add( | ||
this.match('['), | ||
this.assignexpr(), | ||
this.match(']') | ||
); | ||
return node; | ||
}, | ||
propsets: function() { | ||
@@ -1455,5 +1573,5 @@ var node = new Node(Node.PROPTSETS); | ||
} | ||
if(this.look && this.look.content() == '...') { | ||
node.add(this.bindid()); | ||
} | ||
// if(this.look && this.look.content() == '...') { | ||
// node.add(this.bindid()); | ||
// } | ||
return node; | ||
@@ -1460,0 +1578,0 @@ }, |
@@ -320,3 +320,3 @@ define(function(require, exports, module) { | ||
} | ||
//支持es6 | ||
function addParam(params, child) { | ||
@@ -327,5 +327,2 @@ params.leaves().forEach(function(leaf, i) { | ||
} | ||
else if(leaf.name() == JsNode.RESTPARAM) { | ||
child.addParam(leaf.leaves()[1].token().content()); | ||
} | ||
}); | ||
@@ -332,0 +329,0 @@ } |
@@ -68,6 +68,3 @@ define(function(require, exports, module) { | ||
PROGRAM: 'program', | ||
ELEMS: 'elems', | ||
ELEM: 'elem', | ||
CSTSTMT: 'cststmt', | ||
LETSTMT: 'letstmt', | ||
VARSTMT: 'varstmt', | ||
@@ -80,13 +77,3 @@ VARDECL: 'vardecl', | ||
FNPARAMS: 'fnparams', | ||
BINDELEMENT: 'bindelement', | ||
RESTPARAM: 'restparam', | ||
EXPR: 'expr', | ||
CLASSDECL: 'classdecl', | ||
CLASSTAIL: 'classtail', | ||
HERITAGE: 'heritage', | ||
CLASSBODY: 'classbody', | ||
METHOD: 'method', | ||
SUPERSTMT: 'superstmt', | ||
GETFN: 'getfn', | ||
SETFN: 'setfn', | ||
PROGRAM: 'program', | ||
@@ -132,20 +119,7 @@ STMT: 'stmt', | ||
PROPTASSIGN: 'proptassign', | ||
PROPTNAME: 'proptname', | ||
PROPTSETS: 'propsets', | ||
ARGS: 'args', | ||
ARGLIST: 'arglist', | ||
IMPTSTMT: 'imptstmt', | ||
POSTFIXEXPR: 'postfixexpr', | ||
NEWEXPR: 'newexpr', | ||
CALLEXPR: 'callexpr', | ||
ARRBINDPAT: 'arrbindpat', | ||
OBJBINDPAT: 'objbindpat', | ||
BINDPROPT: 'bindpropt', | ||
SINGLENAME: 'singlename', | ||
BINDELEM: 'bindelem', | ||
BINDREST: 'bindrest', | ||
BINDID: 'bindid', | ||
SPREAD: 'spread', | ||
ARRCMPH: 'arrcmph', | ||
CMPHFOR: 'cmphfor', | ||
getKey: function(s) { | ||
@@ -152,0 +126,0 @@ if(!s) { |
@@ -10,2 +10,17 @@ define(function(require, exports, module) { | ||
S[Token.BLANK] = S[Token.TAB] = S[Token.COMMENT] = S[Token.LINE] = S[Token.ENTER] = true; | ||
var NOASSIGN = {}; | ||
NOASSIGN[Node.CNDTEXPR] | ||
= NOASSIGN[Node.LOGOREXPR] | ||
= NOASSIGN[Node.LOGANDEXPR] | ||
= NOASSIGN[Node.BITOREXPR] | ||
= NOASSIGN[Node.BITXOREXPR] | ||
= NOASSIGN[Node.BITANDEXPR] | ||
= NOASSIGN[Node.EQEXPR] | ||
= NOASSIGN[Node.RELTEXPR] | ||
= NOASSIGN[Node.SHIFTEXPR] | ||
= NOASSIGN[Node.ADDEXPR] | ||
= NOASSIGN[Node.MTPLEXPR] | ||
= NOASSIGN[Node.UNARYEXPR] | ||
= NOASSIGN[Node.POSTFIXEXPR] | ||
= true; | ||
var Parser = Class(function(lexer) { | ||
@@ -141,15 +156,6 @@ this.init(lexer); | ||
} | ||
if(['[', '{'].indexOf(this.look.content()) > -1) { | ||
node.add(this.bindpat()); | ||
if(!this.look || this.look.content() != '=') { | ||
this.error('missing = in destructuring declaration'); | ||
} | ||
node.add(this.match(Token.ID, 'missing variable name')); | ||
if(this.look && this.look.content() == '=') { | ||
node.add(this.assign()); | ||
} | ||
else { | ||
node.add(this.match(Token.ID, 'missing variable name')); | ||
if(this.look && this.look.content() == '=') { | ||
node.add(this.assign()); | ||
} | ||
} | ||
return node; | ||
@@ -547,4 +553,4 @@ }, | ||
assignexpr: function(noIn) { | ||
var node = new Node(Node.ASSIGNEXPR), | ||
cndt = this.cndtexpr(noIn); | ||
var node = new Node(Node.ASSIGNEXPR); | ||
var cndt = this.cndtexpr(noIn); | ||
if(this.look && { | ||
@@ -563,3 +569,3 @@ '*=': true, | ||
'=': true | ||
}.hasOwnProperty(this.look.content())) { | ||
}.hasOwnProperty(this.look.content()) && !NOASSIGN.hasOwnProperty(cndt.name())) { | ||
node.add(cndt, this.match(), this.assignexpr(noIn)); | ||
@@ -851,3 +857,3 @@ } | ||
this.match(), | ||
this.match(Token.ID) | ||
this.match(Token.ID, 'missing name after . operator') | ||
); | ||
@@ -887,3 +893,3 @@ } | ||
this.match(), | ||
this.match(Token.ID) | ||
this.match(Token.ID, 'missing name after . operator') | ||
); | ||
@@ -927,3 +933,3 @@ } | ||
this.match(), | ||
this.match(Token.ID) | ||
this.match(Token.ID, 'missing name after . operator') | ||
); | ||
@@ -984,3 +990,3 @@ } | ||
node.add(this.match('[')); | ||
while(this.look && this.look.content() != ']' && this.look.content() != '...') { | ||
while(this.look && this.look.content() != ']') { | ||
if(this.look.content() == ',') { | ||
@@ -991,10 +997,4 @@ node.add(this.match()); | ||
node.add(this.assignexpr()); | ||
if(this.look && this.look.content() == ',') { | ||
node.add(this.match()); | ||
} | ||
} | ||
} | ||
if(this.look.content() == '...') { | ||
node.add(this.spread()); | ||
} | ||
node.add(this.match(']', 'missing ] after element list')); | ||
@@ -1017,44 +1017,15 @@ return node; | ||
var node = new Node(Node.PROPTASSIGN); | ||
if(!this.look) { | ||
this.error(); | ||
switch(this.look.type()) { | ||
case Token.ID: | ||
case Token.STRING: | ||
case Token.NUMBER: | ||
node.add( | ||
this.match(), | ||
this.match(':', 'missing : after property id'), | ||
this.assignexpr() | ||
); | ||
break; | ||
default: | ||
this.error('invalid property id'); | ||
} | ||
if(this.look.content() == 'get') { | ||
node.add(this.match()); | ||
if(!this.look) { | ||
this.error(); | ||
} | ||
if(this.look.content() == ':') { | ||
node.add(this.match(), this.assignexpr()); | ||
} | ||
else { | ||
node.add(this.getfn()); | ||
} | ||
} | ||
else if(this.look.content() == 'set') { | ||
node.add(this.match()); | ||
if(!this.look) { | ||
this.error(); | ||
} | ||
if(this.look.content() == ':') { | ||
node.add(this.match(), this.assignexpr()); | ||
} | ||
else { | ||
node.add(this.setfn()); | ||
} | ||
} | ||
else { | ||
switch(this.look.type()) { | ||
case Token.ID: | ||
case Token.STRING: | ||
case Token.NUMBER: | ||
node.add( | ||
this.match(), | ||
this.match(':', 'missing : after property id'), | ||
this.assignexpr() | ||
); | ||
break; | ||
default: | ||
this.error('invalid property id'); | ||
} | ||
} | ||
return node; | ||
@@ -1061,0 +1032,0 @@ }, |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
29974
1172963