Jsdoc类型普拉特解析器
这个项目是jsdoc类型的解析器。它接受jsdoc类型的表达式,例如 Array<string> 然后创建一个抽象的
语法树(AST)。它很大程度上受到了现有图书馆的启发 洗涤 和 jsdoctypeparser,但是……
不使用 PEG.js相反,它被编写为一个pratt解析器。
您可以在这里找到有关pratt解析器的更多信息:
- https://en.wikipedia.org/wiki/Operator-precedence_parser#Pratt_parsing
- http://journal.stuffwithstuff.com/2011/03/19/pratt-parsers-expression-parsing-made-easy/
- https://matklad.github.io/2020/04/13/simple-but-powerful-pratt-parsing.html
目录表
现场演示
可以在下面找到一个简单的测试表达式的实时演示: https://jsdoc-type-pratt-parser.github.io/jsdoc-type-pratt-parser/
开始
npm install jsdoc-type-pratt-parser
import { parse } from 'jsdoc-type-pratt-parser'
const result = parse('SomeType<string>', 'typescript')
API文档
可以找到API文档 在这里。 它是不完整的,但却是一个很好的起点。请创建问题或pr,如果你没有找到你所期望的。
可用语法
支持三种不同的模式(语法): 'jsdoc', 'closure' 和 'typescript'
转换
在ast上执行的一个常见任务是转换,例如字符串化。这个库包括一些变换和 实现您自己的实用程序。
import { stringify } from 'jsdoc-type-pratt-parser'
const val = stringify({ type: 'JsdocTypeName', value: 'name'}) // -> 'name'
可以使用自定义字符串化 stringifyRules
和 transform:
import { stringifyRules, transform } from 'jsdoc-type-pratt-parser'
const rules = stringifyRules()
// `result` is the current node and `transform` is a function to transform child nodes.
rules.NAME = (result, transform) => 'something else'
const val = transform(rules, { type: 'JsdocTypeName', value: 'name'}) // -> 'something else'
方法来构建自己的转换规则 TransformRules<TransformResultType> 界面还是你
可以建立在 身份规则集 是这样的:
import { identityTransformRules, transform } from 'jsdoc-type-pratt-parser'
const myRules = identityTransformRules()
myRules.NAME = () => ({ type: 'JsdocTypeName', value: 'funky' })
const val = transform(myRules, result)
这个库还支持catharsis和jsdoctypeparser的兼容模式。所提供的转换函数试图 将输出转换为目标库的预期输出。这并不总是与某些类型相同 解析不同。这些模式被认为使转换更容易,但建议使用本机输出作为 这将更统一,将包含更多的信息。
import { parse, catharsisTransform } from 'jsdoc-type-pratt-parser'
const result = catharsisTransform(parse('myType.<string>', 'closure'))
import { parse, jtpTransform } from 'jsdoc-type-pratt-parser'
const result = jtpTransform(parse('myType.<string>', 'closure'))
遍历
方法遍历AST traverse 功能:
import { traverse } from 'jsdoc-type-pratt-parser'
// property is the name of the property on parent that contains node
function onEnter(node, parent, property) {
console.log(node.type)
}
// an onEnter and/or an onLeave function can be supplied
traverse({ type: 'JsdocTypeName', value: 'name'}, onEnter, console.log)
自定义访问者键(按节点) type)可以作为第四个参数提供。他们
优先于内置的 visitorKeys,这对于节点的
这个包不知道的结构(例如,计算属性的ast):
traverse(ast, onEnter, onLeave, {
// Visit the `expression` property of a custom node type
MyCustomNode: ['expression'],
// Nodes of unknown type are visited only if keys are given for them
Identifier: []
})
自定义解析器和stringifier
对于TypeScript的computed属性和方法,请访问JavaScript
(或TypeScript)的解析和字符串化是必需的
中支持的类型 jsdoc-type-pratt-parser). 你可以提供这些
通过提供以下可选参数:
import { parse as espree } from 'espree'
import { generate } from '@es-joy/escodegen'
const parsed = parse(
input,
mode,
{ computedPropertyParser: espree }
)
const stringified = stringify(
result,
generate
)
测试状态
此解析器运行的大多数测试 洗涤 和
jsdoctypeparser. 它比较了不同解析库的结果。如果你
想要找出输出的不同之处,请查看测试中的注释 // This seems to be an error of ... 或
这个 differ 关键字,表示产生不同的结果。
表演
一个简单的 性能比较 使用 Benchmark.js 产生了以下结果:
Testing expression: Name
catharsis x 37,816 ops/sec ±1.22% (1086 runs sampled)
jsdoc-type-pratt-parser x 602,617 ops/sec ±0.16% (1090 runs sampled)
jsdoctypeparser x 53,256 ops/sec ±0.73% (1081 runs sampled)
The fastest was jsdoc-type-pratt-parser
Testing expression: Array<number>
catharsis x 10,124 ops/sec ±0.56% (1084 runs sampled)
jsdoc-type-pratt-parser x 228,660 ops/sec ±0.40% (1084 runs sampled)
jsdoctypeparser x 42,365 ops/sec ±0.60% (1070 runs sampled)
The fastest was jsdoc-type-pratt-parser
Testing expression: { keyA: Type<A | "string val" >, keyB: function(string, B): A }
catharsis x 1,138 ops/sec ±0.66% (1087 runs sampled)
jsdoc-type-pratt-parser x 46,535 ops/sec ±0.47% (1090 runs sampled)
jsdoctypeparser x 18,291 ops/sec ±0.71% (1084 runs sampled)
The fastest was jsdoc-type-pratt-parser
基准测试使用没有缓存的宣泄。
发展
如果您想贡献,请参阅 开发指南 得到一些建议。你可以随意制造问题 信息丢失了。