homunculus
Advanced tools
Comparing version 0.6.7 to 0.7.0
{ | ||
"name": "homunculus", | ||
"version": "0.6.7", | ||
"version": "0.7.0", | ||
"description": "A lexer&parser by Javascript", | ||
@@ -26,3 +26,4 @@ "maintainers": [ | ||
"src/lexer/rule/HtmlRule", | ||
"src/parser" | ||
"src/parser", | ||
"src/util/walk" | ||
] | ||
@@ -29,0 +30,0 @@ } |
# A lexer&parser by Javascript | ||
`homunculus`取自`钢之炼金术师`中的`人造人`,英语亦作`小矮人`,意指底层基石再造 | ||
`homunculus`取自`钢之炼金术师`中的`人造人`,英语亦作`小矮人`,意指底层基石再造。 | ||
@@ -29,2 +29,3 @@ [![NPM version](https://badge.fury.io/js/homunculus.png)](https://npmjs.org/package/homunculus) | ||
* rule | ||
* walk | ||
* lan: | ||
@@ -82,3 +83,3 @@ * js | ||
* parse(code:String):Array<lexer/Token> 传入代码并返回解析后的此法单元token列表 | ||
* tokens():Array<lexer/Token> 返回已解析好的此番单元token列表 | ||
* tokens(plainObject:Boolean = false):Array<lexer/Token> 返回已解析好的此番单元token列表,如果plainObject为true则传回普通对象 | ||
* cache(line:init):void 设置缓冲解析行,每次最多解析几行代码,防止code过大卡死 | ||
@@ -98,4 +99,4 @@ * finish():Boolean 设置cache有用,当前是否解析完毕 | ||
* parse(code:String):Node 传入代码解析并返回语法树 | ||
* ast():Node 返回已解析好的语法树 | ||
* ignore():Node 返回解析中被忽略掉的空白注释等内容 | ||
* ast(plainObject:Boolean = false):Node 返回已解析好的语法树,如果plainObject为true则传回普通对象 | ||
* ignore():Object 返回解析中被忽略掉的空白注释等内容 | ||
@@ -111,2 +112,3 @@ ### lexer/Token | ||
* sIndex(i:int):int 读取/设置token在code中的字符索引 | ||
* isVirtual():Boolean 返回此token是否是虚拟不存在的 | ||
@@ -128,2 +130,3 @@ #### 静态属性 | ||
* token():Token 实际同leaves()一样,不过当name()为Token时children存储的是终结符Token | ||
* isToken():Boolean 返回此节点是否是Token节点 | ||
* parent():Node 返回父节点 | ||
@@ -138,2 +141,10 @@ * prev():Node 返回兄弟前一个节点 | ||
### util/walk | ||
#### 方法 | ||
* simple(node:Node, nodeVisitors:Object, tokenVisitors:Object) 遍历语法树工具。nodeVisitors以树节点名做键,回调做值,回调参数为树节点;tokenVisitors以token类型做键,回调做值,回调参数为token | ||
* simpleIgnore(node:Node, ignore:Object, nodeVisitors:Object, tokenVisitors:Object) 同上,增加第2个参数为忽略掉的空白符等。tokenVisitors的回调增加第2个参数为此token后面的忽略的token数组 | ||
* recursion(node:Node, callback:Function) 递归工具,深度遍历语法树,回调每个节点。回调参数第1个为节点或者token,第2个参数标明是否是token | ||
* plainObject(node:Node):Array 序列化语法树结果为普通类型 | ||
* plainObject(tokens:Array<Token>):Array 序列化tokens结果为普通类型 | ||
#### 特别的,对于css还可以设置添加属性和颜色别名 | ||
@@ -140,0 +151,0 @@ * addValue(v:String):Object 添加未知属性并返回属性hash,仅限此次对象分析 |
@@ -12,2 +12,4 @@ var Lexer = require('./lexer/Lexer'); | ||
var Token = require('./lexer/Token'); | ||
var CssToken = require('./lexer/CssToken'); | ||
var HtmlToken = require('./lexer/HtmlToken'); | ||
@@ -26,2 +28,4 @@ var JsParser = require('./parser/js/Parser'); | ||
var walk = require('./util/walk'); | ||
exports.getClass = function (type, lan) { | ||
@@ -102,3 +106,11 @@ type = (type || '').toLowerCase(); | ||
case 'token': | ||
return Token; | ||
switch (lan) { | ||
case 'css': | ||
return CssToken; | ||
case 'htm': | ||
case 'html': | ||
return HtmlToken; | ||
default: | ||
return Token; | ||
} | ||
case 'rule': | ||
@@ -110,2 +122,3 @@ switch (lan) { | ||
case 'es5': | ||
case 'es6': | ||
case 'ecmascript': | ||
@@ -121,2 +134,4 @@ return EcmascriptRule; | ||
} | ||
case 'walk': | ||
return walk; | ||
default: | ||
@@ -123,0 +138,0 @@ throw new Error('Unsupport Class Type: ' + type); |
var Lexer = require('./Lexer'); | ||
var Token = require('./Token'); | ||
var Token = require('./CssToken'); | ||
var character = require('../util/character'); | ||
@@ -4,0 +4,0 @@ var RegMatch = require('./match/RegMatch'); |
var Class = require('../util/Class'); | ||
var character = require('../util/character'); | ||
var Token = require('./Token'); | ||
var Token = require('./HtmlToken'); | ||
var HtmlLexer = Class(function(rule) { | ||
@@ -5,0 +5,0 @@ this.rule = rule; //当前语法规则 |
var Class = require('../util/Class'); | ||
var character = require('../util/character'); | ||
var Token = require('./Token'); | ||
var walk = require('../util/walk'); | ||
var Lexer = Class(function(rule) { | ||
@@ -33,3 +34,6 @@ this.rule = rule; //当前语法规则 | ||
}, | ||
tokens: function() { | ||
tokens: function(plainObject) { | ||
if(plainObject) { | ||
return walk.plainObject(this.tokenList); | ||
} | ||
return this.tokenList; | ||
@@ -36,0 +40,0 @@ }, |
@@ -7,3 +7,3 @@ var Rule = require('./Rule'); | ||
var RegMatch = require('../match/RegMatch'); | ||
var Token = require('../Token'); | ||
var Token = require('../CssToken'); | ||
var character = require('../../util/character'); | ||
@@ -102,3 +102,7 @@ var CssRule = Rule.extend(function() { | ||
'@top-right': true, | ||
'@extend': true | ||
'@extend': true, | ||
'@if': true, | ||
'@elseif': true, | ||
'@else': true, | ||
'@for': true | ||
}.hasOwnProperty(s)) { | ||
@@ -105,0 +109,0 @@ token.type(Token.VARS); |
@@ -6,3 +6,3 @@ var Rule = require('./Rule'); | ||
var character = require('../../util/character'); | ||
var Token = require('../Token'); | ||
var Token = require('../HtmlToken'); | ||
var HtmlRule = Rule.extend(function() { | ||
@@ -9,0 +9,0 @@ var self = this; |
@@ -72,4 +72,8 @@ var Class = require('../util/Class'); | ||
tid--; | ||
}, | ||
isVirtual: function() { | ||
return this.t == Token.VIRTUAL; | ||
} | ||
}).statics({ | ||
//公用 | ||
IGNORE: -2, | ||
@@ -86,26 +90,18 @@ VIRTUAL: -1, | ||
SIGN: 8, | ||
KEYWORD: 10, | ||
//js部分 | ||
REG: 9, | ||
KEYWORD: 10, | ||
//es6 | ||
TEMPLATE: 13, | ||
//仅java | ||
ANNOT: 11, | ||
HEAD: 12, | ||
TEMPLATE: 13, | ||
//基本无用 | ||
ENTER: 14, | ||
PROPERTY: 15, | ||
VARS: 16, | ||
HACK: 17, | ||
IMPORTANT: 18, | ||
PSEUDO: 19, | ||
UNITS: 20, | ||
SELECTOR: 21, | ||
ATTR: 22, | ||
COLOR: 23, | ||
DATA: 24, | ||
TEXT: 25, | ||
MARK: 26, | ||
type: function(tag) { | ||
var self = this; | ||
if(character.isUndefined(types)) { | ||
types = []; | ||
Object.keys(Token).forEach(function(o) { | ||
if(typeof Token[o] == 'number') { | ||
types[Token[o]] = o; | ||
Object.keys(self).forEach(function(o) { | ||
if(typeof self[o] == 'number') { | ||
types[self[o]] = o; | ||
} | ||
@@ -112,0 +108,0 @@ }); |
@@ -67,2 +67,3 @@ var INode = require('../Node'); | ||
REGEXP: 'regexp', | ||
IFSTMT: 'ifstmt', | ||
getKey: function(s) { | ||
@@ -69,0 +70,0 @@ if(!s) { |
@@ -5,5 +5,4 @@ var IParser = require('../Parser'); | ||
var Rule = require('../../lexer/rule/CssRule'); | ||
var Token = require('../../lexer/Token'); | ||
var Token = require('../../lexer/CssToken'); | ||
var Node = require('./Node'); | ||
var needValue = require('./needValue'); | ||
var S = {}; | ||
@@ -142,4 +141,6 @@ S[Token.BLANK] = S[Token.TAB] = S[Token.COMMENT] = S[Token.LINE] = true; | ||
return this.extend(); | ||
case '@if': | ||
return this.ifstmt(); | ||
default: | ||
this.error(); | ||
this.error('unknow head'); | ||
} | ||
@@ -635,7 +636,4 @@ }, | ||
name = k.first().token().content().toLowerCase(); | ||
if(needValue(k) | ||
|| this.look && this.look.content() == ':') { | ||
node.add(this.match(':')); | ||
node.add(this.value(name, noC)); | ||
} | ||
node.add(this.match(':')); | ||
node.add(this.value(name, noC)); | ||
while(this.look && this.look.type() == Token.HACK) { | ||
@@ -1330,2 +1328,21 @@ node.add(this.match()); | ||
}, | ||
ifstmt: function() { | ||
var node = new Node(Node.IFSTMT); | ||
node.add( | ||
this.match(), | ||
this.match('('), | ||
this.addexpr(), | ||
this.match(')'), | ||
this.block() | ||
); | ||
if(this.look) { | ||
if(this.look.content() == '@elseif') { | ||
node.add(this.ifstmt()); | ||
} | ||
else if(this.look.content() == '@else') { | ||
node.add(this.match(), this.block()); | ||
} | ||
} | ||
return node; | ||
}, | ||
match: function(type, msg) { | ||
@@ -1332,0 +1349,0 @@ //未定义为所有 |
@@ -5,3 +5,3 @@ var IParser = require('../Parser'); | ||
var Rule = require('../../lexer/rule/HtmlRule'); | ||
var Token = require('../../lexer/Token'); | ||
var Token = require('../../lexer/HtmlToken'); | ||
var Node = require('./Node'); | ||
@@ -8,0 +8,0 @@ var S = {}; |
@@ -122,2 +122,8 @@ var Class = require('../util/Class'); | ||
return this.ne; | ||
}, | ||
isToken: function() { | ||
return this.type == Node.TOKEN; | ||
}, | ||
toString: function() { | ||
return this.name(); | ||
} | ||
@@ -124,0 +130,0 @@ }).statics({ |
var Class = require('../util/Class'); | ||
var walk = require('../util/walk'); | ||
var Parser = Class(function(lexer) { | ||
@@ -11,3 +12,6 @@ this.lexer = lexer; | ||
}, | ||
ast: function() { | ||
ast: function(plainObject) { | ||
if(plainObject) { | ||
return walk.plainObject(this.tree); | ||
} | ||
return this.tree; | ||
@@ -14,0 +18,0 @@ }, |
@@ -12,2 +12,4 @@ define(function(require, exports, module) {var Lexer = require('./lexer/Lexer'); | ||
var Token = require('./lexer/Token'); | ||
var CssToken = require('./lexer/CssToken'); | ||
var HtmlToken = require('./lexer/HtmlToken'); | ||
@@ -26,2 +28,4 @@ var JsParser = require('./parser/js/Parser'); | ||
var walk = require('./util/walk'); | ||
exports.getClass = function (type, lan) { | ||
@@ -102,3 +106,11 @@ type = (type || '').toLowerCase(); | ||
case 'token': | ||
return Token; | ||
switch (lan) { | ||
case 'css': | ||
return CssToken; | ||
case 'htm': | ||
case 'html': | ||
return HtmlToken; | ||
default: | ||
return Token; | ||
} | ||
case 'rule': | ||
@@ -110,2 +122,3 @@ switch (lan) { | ||
case 'es5': | ||
case 'es6': | ||
case 'ecmascript': | ||
@@ -121,2 +134,4 @@ return EcmascriptRule; | ||
} | ||
case 'walk': | ||
return walk; | ||
default: | ||
@@ -123,0 +138,0 @@ throw new Error('Unsupport Class Type: ' + type); |
define(function(require, exports, module) {var Lexer = require('./Lexer'); | ||
var Token = require('./Token'); | ||
var Token = require('./CssToken'); | ||
var character = require('../util/character'); | ||
@@ -4,0 +4,0 @@ var RegMatch = require('./match/RegMatch'); |
define(function(require, exports, module) {var Class = require('../util/Class'); | ||
var character = require('../util/character'); | ||
var Token = require('./Token'); | ||
var Token = require('./HtmlToken'); | ||
var HtmlLexer = Class(function(rule) { | ||
@@ -5,0 +5,0 @@ this.rule = rule; //当前语法规则 |
define(function(require, exports, module) {var Class = require('../util/Class'); | ||
var character = require('../util/character'); | ||
var Token = require('./Token'); | ||
var walk = require('../util/walk'); | ||
var Lexer = Class(function(rule) { | ||
@@ -33,3 +34,6 @@ this.rule = rule; //当前语法规则 | ||
}, | ||
tokens: function() { | ||
tokens: function(plainObject) { | ||
if(plainObject) { | ||
return walk.plainObject(this.tokenList); | ||
} | ||
return this.tokenList; | ||
@@ -36,0 +40,0 @@ }, |
@@ -7,3 +7,3 @@ define(function(require, exports, module) {var Rule = require('./Rule'); | ||
var RegMatch = require('../match/RegMatch'); | ||
var Token = require('../Token'); | ||
var Token = require('../CssToken'); | ||
var character = require('../../util/character'); | ||
@@ -102,3 +102,7 @@ var CssRule = Rule.extend(function() { | ||
'@top-right': true, | ||
'@extend': true | ||
'@extend': true, | ||
'@if': true, | ||
'@elseif': true, | ||
'@else': true, | ||
'@for': true | ||
}.hasOwnProperty(s)) { | ||
@@ -105,0 +109,0 @@ token.type(Token.VARS); |
@@ -6,3 +6,3 @@ define(function(require, exports, module) {var Rule = require('./Rule'); | ||
var character = require('../../util/character'); | ||
var Token = require('../Token'); | ||
var Token = require('../HtmlToken'); | ||
var HtmlRule = Rule.extend(function() { | ||
@@ -9,0 +9,0 @@ var self = this; |
@@ -72,4 +72,8 @@ define(function(require, exports, module) {var Class = require('../util/Class'); | ||
tid--; | ||
}, | ||
isVirtual: function() { | ||
return this.t == Token.VIRTUAL; | ||
} | ||
}).statics({ | ||
//公用 | ||
IGNORE: -2, | ||
@@ -86,26 +90,18 @@ VIRTUAL: -1, | ||
SIGN: 8, | ||
KEYWORD: 10, | ||
//js部分 | ||
REG: 9, | ||
KEYWORD: 10, | ||
//es6 | ||
TEMPLATE: 13, | ||
//仅java | ||
ANNOT: 11, | ||
HEAD: 12, | ||
TEMPLATE: 13, | ||
//基本无用 | ||
ENTER: 14, | ||
PROPERTY: 15, | ||
VARS: 16, | ||
HACK: 17, | ||
IMPORTANT: 18, | ||
PSEUDO: 19, | ||
UNITS: 20, | ||
SELECTOR: 21, | ||
ATTR: 22, | ||
COLOR: 23, | ||
DATA: 24, | ||
TEXT: 25, | ||
MARK: 26, | ||
type: function(tag) { | ||
var self = this; | ||
if(character.isUndefined(types)) { | ||
types = []; | ||
Object.keys(Token).forEach(function(o) { | ||
if(typeof Token[o] == 'number') { | ||
types[Token[o]] = o; | ||
Object.keys(self).forEach(function(o) { | ||
if(typeof self[o] == 'number') { | ||
types[self[o]] = o; | ||
} | ||
@@ -112,0 +108,0 @@ }); |
@@ -67,2 +67,3 @@ define(function(require, exports, module) {var INode = require('../Node'); | ||
REGEXP: 'regexp', | ||
IFSTMT: 'ifstmt', | ||
getKey: function(s) { | ||
@@ -69,0 +70,0 @@ if(!s) { |
@@ -5,5 +5,4 @@ define(function(require, exports, module) {var IParser = require('../Parser'); | ||
var Rule = require('../../lexer/rule/CssRule'); | ||
var Token = require('../../lexer/Token'); | ||
var Token = require('../../lexer/CssToken'); | ||
var Node = require('./Node'); | ||
var needValue = require('./needValue'); | ||
var S = {}; | ||
@@ -142,4 +141,6 @@ S[Token.BLANK] = S[Token.TAB] = S[Token.COMMENT] = S[Token.LINE] = true; | ||
return this.extend(); | ||
case '@if': | ||
return this.ifstmt(); | ||
default: | ||
this.error(); | ||
this.error('unknow head'); | ||
} | ||
@@ -635,7 +636,4 @@ }, | ||
name = k.first().token().content().toLowerCase(); | ||
if(needValue(k) | ||
|| this.look && this.look.content() == ':') { | ||
node.add(this.match(':')); | ||
node.add(this.value(name, noC)); | ||
} | ||
node.add(this.match(':')); | ||
node.add(this.value(name, noC)); | ||
while(this.look && this.look.type() == Token.HACK) { | ||
@@ -1330,2 +1328,21 @@ node.add(this.match()); | ||
}, | ||
ifstmt: function() { | ||
var node = new Node(Node.IFSTMT); | ||
node.add( | ||
this.match(), | ||
this.match('('), | ||
this.addexpr(), | ||
this.match(')'), | ||
this.block() | ||
); | ||
if(this.look) { | ||
if(this.look.content() == '@elseif') { | ||
node.add(this.ifstmt()); | ||
} | ||
else if(this.look.content() == '@else') { | ||
node.add(this.match(), this.block()); | ||
} | ||
} | ||
return node; | ||
}, | ||
match: function(type, msg) { | ||
@@ -1332,0 +1349,0 @@ //未定义为所有 |
@@ -5,3 +5,3 @@ define(function(require, exports, module) {var IParser = require('../Parser'); | ||
var Rule = require('../../lexer/rule/HtmlRule'); | ||
var Token = require('../../lexer/Token'); | ||
var Token = require('../../lexer/HtmlToken'); | ||
var Node = require('./Node'); | ||
@@ -8,0 +8,0 @@ var S = {}; |
@@ -122,2 +122,8 @@ define(function(require, exports, module) {var Class = require('../util/Class'); | ||
return this.ne; | ||
}, | ||
isToken: function() { | ||
return this.type == Node.TOKEN; | ||
}, | ||
toString: function() { | ||
return this.name(); | ||
} | ||
@@ -124,0 +130,0 @@ }).statics({ |
define(function(require, exports, module) {var Class = require('../util/Class'); | ||
var walk = require('../util/walk'); | ||
var Parser = Class(function(lexer) { | ||
@@ -11,3 +12,6 @@ this.lexer = lexer; | ||
}, | ||
ast: function() { | ||
ast: function(plainObject) { | ||
if(plainObject) { | ||
return walk.plainObject(this.tree); | ||
} | ||
return this.tree; | ||
@@ -14,0 +18,0 @@ }, |
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
576293
85
16691
159
75