Add existing to tracked
This commit is contained in:
+20
@@ -0,0 +1,20 @@
|
||||
Copyright (c) 2013 Stephen Oney, https://ericsmekens.github.io/jsep/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
+208
@@ -0,0 +1,208 @@
|
||||
## jsep: A Tiny JavaScript Expression Parser
|
||||
|
||||
[jsep](https://ericsmekens.github.io/jsep/) is a simple expression parser written in JavaScript. It can parse JavaScript expressions but not operations. The difference between expressions and operations is akin to the difference between a cell in an Excel spreadsheet vs. a proper JavaScript program.
|
||||
|
||||
### Why jsep?
|
||||
|
||||
I wanted a lightweight, tiny parser to be included in one of my other libraries. [esprima](http://esprima.org/) and other parsers are great, but had more power than I need and were *way* too large to be included in a library that I wanted to keep relatively small.
|
||||
|
||||
jsep's output is almost identical to [esprima's](http://esprima.org/doc/index.html#ast), which is in turn based on [SpiderMonkey's](https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API).
|
||||
|
||||
### Custom Build
|
||||
|
||||
While in the jsep project directory, run:
|
||||
|
||||
```bash
|
||||
npm install
|
||||
npm run default
|
||||
```
|
||||
|
||||
The jsep built files will be in the build/ directory.
|
||||
|
||||
### Usage
|
||||
|
||||
#### Client-side
|
||||
|
||||
```html
|
||||
<script type="module">
|
||||
import jsep from '/PATH/TO/jsep.min.js';
|
||||
const parsed = jsep('1 + 1');
|
||||
</script>
|
||||
|
||||
<script src="/PATH/TO/jsep.iife.min.js"></script>
|
||||
...
|
||||
let parse_tree = jsep("1 + 1");
|
||||
```
|
||||
|
||||
#### Node.JS
|
||||
|
||||
First, run `npm install jsep`. Then, in your source file:
|
||||
|
||||
```javascript
|
||||
// ESM:
|
||||
import jsep from 'jsep';
|
||||
const parse_tree = jsep('1 + 1');
|
||||
|
||||
// or:
|
||||
import { Jsep } from 'jsep';
|
||||
const parse_tree = Jsep.parse('1 + 1');
|
||||
|
||||
|
||||
// CJS:
|
||||
const jsep = require('jsep').default;
|
||||
const parsed = jsep('1 + 1');
|
||||
|
||||
// or:
|
||||
const { Jsep } = require('jsep');
|
||||
const parse_tree = Jsep.parse('1 + 1');
|
||||
```
|
||||
|
||||
#### Custom Operators
|
||||
|
||||
```javascript
|
||||
// Add a custom ^ binary operator with precedence 10
|
||||
// (Note that higher number = higher precedence)
|
||||
jsep.addBinaryOp("^", 10);
|
||||
|
||||
// Add exponentiation operator (right-to-left)
|
||||
jsep.addBinaryOp('**', 11, true); // now included by default
|
||||
|
||||
// Add a custom @ unary operator
|
||||
jsep.addUnaryOp('@');
|
||||
|
||||
// Remove a binary operator
|
||||
jsep.removeBinaryOp(">>>");
|
||||
|
||||
// Remove a unary operator
|
||||
jsep.removeUnaryOp("~");
|
||||
```
|
||||
|
||||
#### Custom Identifiers
|
||||
|
||||
You can add or remove additional valid identifier chars. ('_' and '$' are already treated like this.)
|
||||
|
||||
```javascript
|
||||
// Add a custom @ identifier
|
||||
jsep.addIdentifierChar("@");
|
||||
|
||||
// Removes a custom @ identifier
|
||||
jsep.removeIdentifierChar('@');
|
||||
```
|
||||
|
||||
#### Custom Literals
|
||||
|
||||
You can add or remove additional valid literals. By default, only `true`, `false`, and `null` are defined
|
||||
```javascript
|
||||
// Add standard JS literals:
|
||||
jsep.addLiteral('undefined', undefined);
|
||||
jsep.addLiteral('Infinity', Infinity);
|
||||
jsep.addLiteral('NaN', NaN);
|
||||
|
||||
// Remove "null" literal from default definition
|
||||
jsep.removeLiteral('null');
|
||||
```
|
||||
|
||||
### Plugins
|
||||
JSEP supports defining custom hooks for extending or modifying the expression parsing.
|
||||
Plugins are registered by calling `jsep.plugins.register()` with the plugin(s) as the argument(s).
|
||||
|
||||
#### JSEP-provided plugins:
|
||||
| | |
|
||||
|-----------------------------------|-------------------------------------------------------------------------------------------|
|
||||
| [ternary](packages/ternary) | Built-in by default, adds support for ternary `a ? b : c` expressions |
|
||||
| [arrow](packages/arrow) | Adds arrow-function support: `v => !!v` |
|
||||
| [assignment](packages/assignment) | Adds assignment and update expression support: `a = 2`, `a++` |
|
||||
| [comment](packages/comment) | Adds support for ignoring comments: `a /* ignore this */ > 1 // ignore this too` |
|
||||
| [new](packages/new) | Adds 'new' keyword support: `new Date()` |
|
||||
| [numbers](packages/numbers) | Adds hex, octal, and binary number support, ignore _ char |
|
||||
| [object](packages/object) | Adds object expression support: `{ a: 1, b: { c }}` |
|
||||
| [regex](packages/regex) | Adds support for regular expression literals: `/[a-z]{2}/ig` |
|
||||
| [spread](packages/spread) | Adds support for the spread operator, `fn(...[1, ...a])`. Works with `object` plugin, too |
|
||||
| [template](packages/template) | Adds template literal support: `` `hi ${name}` `` |
|
||||
| | |
|
||||
|
||||
#### How to add plugins:
|
||||
Plugins have a `name` property so that they can only be registered once.
|
||||
Any subsequent registrations will have no effect. Add a plugin by registering it with JSEP:
|
||||
|
||||
```javascript
|
||||
import jsep from 'jsep';
|
||||
import ternary from '@jsep-plugin/ternary';
|
||||
import object from '@jsep-plugin/object';
|
||||
jsep.plugins.register(object);
|
||||
jsep.plugins.register(ternary, object);
|
||||
```
|
||||
|
||||
#### List plugins:
|
||||
Plugins are stored in an object, keyed by their name.
|
||||
They can be retrieved through `jsep.plugins.registered`.
|
||||
|
||||
#### Writing Your Own Plugin:
|
||||
Plugins are objects with two properties: `name` and `init`.
|
||||
Here's a simple plugin example:
|
||||
```javascript
|
||||
const plugin = {
|
||||
name: 'the plugin',
|
||||
init(jsep) {
|
||||
jsep.addIdentifierChar('@');
|
||||
jsep.hooks.add('gobble-expression', function myPlugin(env) {
|
||||
if (this.char === '@') {
|
||||
this.index += 1;
|
||||
env.node = {
|
||||
type: 'MyCustom@Detector',
|
||||
};
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
||||
```
|
||||
This example would treat the `@` character as a custom expression, returning
|
||||
a node of type `MyCustom@Detector`.
|
||||
|
||||
##### Hooks
|
||||
Most plugins will make use of hooks to modify the parsing behavior of jsep.
|
||||
All hooks are bound to the jsep instance, are called with a single argument, and return void.
|
||||
The `this` context provides access to the internal parsing methods of jsep
|
||||
to allow reuse as needed. Some hook types will pass an object that allows reading/writing
|
||||
the `node` property as needed.
|
||||
|
||||
##### Hook Types
|
||||
* `before-all`: called just before starting all expression parsing.
|
||||
* `after-all`: called after parsing all. Read/Write `arg.node` as required.
|
||||
* `gobble-expression`: called just before attempting to parse an expression. Set `arg.node` as required.
|
||||
* `after-expression`: called just after parsing an expression. Read/Write `arg.node` as required.
|
||||
* `gobble-token`: called just before attempting to parse a token. Set `arg.node` as required.
|
||||
* `after-token`: called just after parsing a token. Read/Write `arg.node` as required.
|
||||
* `gobble-spaces`: called when gobbling whitespace.
|
||||
|
||||
##### The `this` context of Hooks
|
||||
```typescript
|
||||
export interface HookScope {
|
||||
index: number;
|
||||
readonly expr: string;
|
||||
readonly char: string; // current character of the expression
|
||||
readonly code: number; // current character code of the expression
|
||||
gobbleSpaces: () => void;
|
||||
gobbleExpressions: (untilICode?: number) => Expression[];
|
||||
gobbleExpression: () => Expression;
|
||||
gobbleBinaryOp: () => PossibleExpression;
|
||||
gobbleBinaryExpression: () => PossibleExpression;
|
||||
gobbleToken: () => PossibleExpression;
|
||||
gobbleTokenProperty: (node: Expression) => Expression;
|
||||
gobbleNumericLiteral: () => PossibleExpression;
|
||||
gobbleStringLiteral: () => PossibleExpression;
|
||||
gobbleIdentifier: () => PossibleExpression;
|
||||
gobbleArguments: (untilICode: number) => PossibleExpression;
|
||||
gobbleGroup: () => Expression;
|
||||
gobbleArray: () => PossibleExpression;
|
||||
throwError: (msg: string) => never;
|
||||
}
|
||||
```
|
||||
|
||||
### License
|
||||
|
||||
jsep is under the MIT license. See LICENSE file.
|
||||
|
||||
### Thanks
|
||||
|
||||
Some parts of the latest version of jsep were adapted from the esprima parser.
|
||||
+1129
File diff suppressed because it is too large
Load Diff
+1
File diff suppressed because one or more lines are too long
+2
File diff suppressed because one or more lines are too long
+1
File diff suppressed because one or more lines are too long
+3
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"type": "commonjs"
|
||||
}
|
||||
+1132
File diff suppressed because it is too large
Load Diff
+1
File diff suppressed because one or more lines are too long
+2
File diff suppressed because one or more lines are too long
+1
File diff suppressed because one or more lines are too long
+1126
File diff suppressed because it is too large
Load Diff
+2
File diff suppressed because one or more lines are too long
+1
File diff suppressed because one or more lines are too long
+153
@@ -0,0 +1,153 @@
|
||||
{
|
||||
"name": "jsep",
|
||||
"version": "1.4.0",
|
||||
"description": "a tiny JavaScript expression parser",
|
||||
"author": "Stephen Oney <swloney@gmail.com> (http://from.so/)",
|
||||
"maintainers": [
|
||||
"Eric Smekens (https://github.com/EricSmekens)",
|
||||
"Lea Verou (https://github.com/LeaVerou)"
|
||||
],
|
||||
"homepage": "https://ericsmekens.github.io/jsep/",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/EricSmekens/jsep.git"
|
||||
},
|
||||
"type": "module",
|
||||
"main": "./dist/cjs/jsep.cjs.js",
|
||||
"module": "./dist/jsep.js",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./typings/tsd.d.ts",
|
||||
"require": "./dist/cjs/jsep.cjs.js",
|
||||
"default": "./dist/jsep.js"
|
||||
}
|
||||
},
|
||||
"typings": "typings/tsd.d.ts",
|
||||
"private": false,
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^13.1.0",
|
||||
"@commitlint/config-angular": "^13.1.0",
|
||||
"@rollup/plugin-replace": "^2.4.2",
|
||||
"@semantic-release/changelog": "^5.0.1",
|
||||
"@semantic-release/exec": "^6.0.3",
|
||||
"@semantic-release/git": "^9.0.0",
|
||||
"benchmark": "^2.1.4",
|
||||
"docco": "^0.9.1",
|
||||
"eslint": "^7.23.0",
|
||||
"http-server": "^14.1.1",
|
||||
"husky": "^7.0.0",
|
||||
"node-qunit-puppeteer": "^2.1.2",
|
||||
"puppeteer": "^19.9.0",
|
||||
"rollup": "^2.44.0",
|
||||
"rollup-plugin-delete": "^2.0.0",
|
||||
"rollup-plugin-terser": "^7.0.2",
|
||||
"semantic-release-monorepo": "^7.0.5",
|
||||
"semantic-release-plus": "^18.4.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.16.0"
|
||||
},
|
||||
"directories": {
|
||||
"test": "test"
|
||||
},
|
||||
"release": {
|
||||
"commitPaths": [
|
||||
"src/",
|
||||
"packages/ternary/src/",
|
||||
"types",
|
||||
"typings/",
|
||||
".npmignore",
|
||||
"package*.json",
|
||||
"rollup*.js"
|
||||
],
|
||||
"branches": [
|
||||
"master",
|
||||
{
|
||||
"name": "alpha",
|
||||
"prerelease": true
|
||||
},
|
||||
{
|
||||
"name": "beta",
|
||||
"prerelease": true
|
||||
}
|
||||
],
|
||||
"plugins": [
|
||||
[
|
||||
"@semantic-release/commit-analyzer",
|
||||
{
|
||||
"preset": "angular",
|
||||
"parserOpts": {
|
||||
"noteKeywords": [
|
||||
"BREAKING CHANGE",
|
||||
"BREAKING CHANGES",
|
||||
"BREAKING"
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
"@semantic-release/release-notes-generator",
|
||||
{
|
||||
"preset": "angular",
|
||||
"parserOpts": {
|
||||
"noteKeywords": [
|
||||
"BREAKING CHANGE",
|
||||
"BREAKING CHANGES",
|
||||
"BREAKING"
|
||||
]
|
||||
},
|
||||
"writerOpts": {
|
||||
"commitsSort": [
|
||||
"scope",
|
||||
"subject"
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"@semantic-release/changelog",
|
||||
[
|
||||
"@semantic-release/exec",
|
||||
{
|
||||
"prepareCmd": "NEXT_VERSION=${nextRelease.version} pnpm run build"
|
||||
}
|
||||
],
|
||||
[
|
||||
"@semantic-release/npm",
|
||||
{
|
||||
"tarballDir": "./"
|
||||
}
|
||||
],
|
||||
[
|
||||
"@semantic-release/git",
|
||||
{
|
||||
"message": "build: ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
|
||||
}
|
||||
],
|
||||
[
|
||||
"@semantic-release/github",
|
||||
{
|
||||
"assets": [
|
||||
{
|
||||
"path": "./*.tgz",
|
||||
"label": "build"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"scripts": {
|
||||
"default": "npm run lint && npm run build:all && npm run test:all && npm run docco",
|
||||
"build": "npx rollup -c && cp package-cjs.json dist/cjs/package.json",
|
||||
"build:watch": "npx rollup -c --watch",
|
||||
"build:all": "pnpm run build -r",
|
||||
"test": "npx http-server -p 49649 --silent & npx node-qunit-puppeteer http://localhost:49649/test/unit_tests.html",
|
||||
"test:all": "npx http-server -p 49649 --silent & pnpm run test -r --workspace-concurrency=1",
|
||||
"test:performance": "node test/performance.test.js",
|
||||
"docco": "npx docco src/jsep.js --css=src/docco.css --output=annotated_source/",
|
||||
"lint": "npx eslint src/**/*.js test/*.js test/packages/**/*.js packages/**/*.js",
|
||||
"prepare": "husky install",
|
||||
"release": "./release.sh"
|
||||
}
|
||||
}
|
||||
+180
@@ -0,0 +1,180 @@
|
||||
declare module 'jsep' {
|
||||
|
||||
namespace jsep {
|
||||
export type baseTypes = string | number | boolean | RegExp | null | undefined | object;
|
||||
export interface Expression {
|
||||
type: string;
|
||||
[key: string]: baseTypes | Expression | Array<baseTypes | Expression>;
|
||||
}
|
||||
|
||||
export interface ArrayExpression extends Expression {
|
||||
type: 'ArrayExpression';
|
||||
/** The expression can be null in the case of array holes ([ , , ]) */
|
||||
elements: Array<null | Expression>;
|
||||
}
|
||||
|
||||
export interface BinaryExpression extends Expression {
|
||||
type: 'BinaryExpression';
|
||||
operator: string;
|
||||
left: Expression;
|
||||
right: Expression;
|
||||
}
|
||||
|
||||
export interface CallExpression extends Expression {
|
||||
type: 'CallExpression';
|
||||
arguments: Expression[];
|
||||
callee: Expression;
|
||||
}
|
||||
|
||||
export interface Compound extends Expression {
|
||||
type: 'Compound';
|
||||
body: Expression[];
|
||||
}
|
||||
|
||||
export interface SequenceExpression extends Expression {
|
||||
type: 'SequenceExpression';
|
||||
expressions: Expression[];
|
||||
}
|
||||
|
||||
export interface ConditionalExpression extends Expression {
|
||||
type: 'ConditionalExpression';
|
||||
test: Expression;
|
||||
consequent: Expression;
|
||||
alternate: Expression;
|
||||
}
|
||||
|
||||
export interface Identifier extends Expression {
|
||||
type: 'Identifier';
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface Literal extends Expression {
|
||||
type: 'Literal';
|
||||
value: boolean | number | string | RegExp | null;
|
||||
raw: string;
|
||||
}
|
||||
|
||||
export interface MemberExpression extends Expression {
|
||||
type: 'MemberExpression';
|
||||
computed: boolean;
|
||||
object: Expression;
|
||||
property: Expression;
|
||||
optional?: boolean;
|
||||
}
|
||||
|
||||
export interface ThisExpression extends Expression {
|
||||
type: 'ThisExpression';
|
||||
}
|
||||
|
||||
export interface UnaryExpression extends Expression {
|
||||
type: 'UnaryExpression';
|
||||
operator: string;
|
||||
argument: Expression;
|
||||
prefix: boolean;
|
||||
}
|
||||
|
||||
export type ExpressionType =
|
||||
'Compound'
|
||||
| 'SequenceExpression'
|
||||
| 'Identifier'
|
||||
| 'MemberExpression'
|
||||
| 'Literal'
|
||||
| 'ThisExpression'
|
||||
| 'CallExpression'
|
||||
| 'UnaryExpression'
|
||||
| 'BinaryExpression'
|
||||
| 'ConditionalExpression'
|
||||
| 'ArrayExpression';
|
||||
|
||||
export type CoreExpression =
|
||||
ArrayExpression
|
||||
| BinaryExpression
|
||||
| CallExpression
|
||||
| Compound
|
||||
| SequenceExpression
|
||||
| ConditionalExpression
|
||||
| Identifier
|
||||
| Literal
|
||||
| MemberExpression
|
||||
| ThisExpression
|
||||
| UnaryExpression;
|
||||
|
||||
export type PossibleExpression = Expression | undefined;
|
||||
export interface HookScope {
|
||||
index: number;
|
||||
readonly expr: string;
|
||||
readonly char: string; // current character of the expression
|
||||
readonly code: number; // current character code of the expression
|
||||
gobbleSpaces: () => void;
|
||||
gobbleExpressions: (untilICode?: number) => Expression[];
|
||||
gobbleExpression: () => Expression;
|
||||
gobbleBinaryOp: () => PossibleExpression;
|
||||
gobbleBinaryExpression: () => PossibleExpression;
|
||||
gobbleToken: () => PossibleExpression;
|
||||
gobbleTokenProperty: (node: Expression) => Expression
|
||||
gobbleNumericLiteral: () => PossibleExpression;
|
||||
gobbleStringLiteral: () => PossibleExpression;
|
||||
gobbleIdentifier: () => PossibleExpression;
|
||||
gobbleArguments: (untilICode: number) => PossibleExpression;
|
||||
gobbleGroup: () => Expression;
|
||||
gobbleArray: () => PossibleExpression;
|
||||
throwError: (msg: string) => never;
|
||||
}
|
||||
|
||||
export type HookType = 'gobble-expression' | 'after-expression' | 'gobble-token' | 'after-token' | 'gobble-spaces';
|
||||
export type HookCallback = (this: HookScope, env: { node?: Expression }) => void;
|
||||
type HookTypeObj = Partial<{ [key in HookType]: HookCallback}>
|
||||
|
||||
export interface IHooks extends HookTypeObj {
|
||||
add(name: HookType, cb: HookCallback, first?: boolean): void;
|
||||
add(obj: { [name in HookType]: HookCallback }, first?: boolean): void;
|
||||
run(name: string, env: { context?: typeof jsep, node?: Expression }): void;
|
||||
}
|
||||
let hooks: IHooks;
|
||||
|
||||
export interface IPlugin {
|
||||
name: string;
|
||||
init: (this: typeof jsep) => void;
|
||||
}
|
||||
export interface IPlugins {
|
||||
registered: { [name: string]: IPlugin };
|
||||
register: (...plugins: IPlugin[]) => void;
|
||||
}
|
||||
let plugins: IPlugins;
|
||||
|
||||
let unary_ops: { [op: string]: any };
|
||||
let binary_ops: { [op: string]: number };
|
||||
let right_associative: Set<string>;
|
||||
let additional_identifier_chars: Set<string>;
|
||||
let literals: { [literal: string]: any };
|
||||
let this_str: string;
|
||||
|
||||
function addBinaryOp(operatorName: string, precedence: number, rightToLeft?: boolean): void;
|
||||
|
||||
function addUnaryOp(operatorName: string): void;
|
||||
|
||||
function addLiteral(literalName: string, literalValue: any): void;
|
||||
|
||||
function addIdentifierChar(identifierName: string): void;
|
||||
|
||||
function removeBinaryOp(operatorName: string): void;
|
||||
|
||||
function removeUnaryOp(operatorName: string): void;
|
||||
|
||||
function removeLiteral(literalName: string): void;
|
||||
|
||||
function removeIdentifierChar(identifierName: string): void;
|
||||
|
||||
function removeAllBinaryOps(): void;
|
||||
|
||||
function removeAllUnaryOps(): void;
|
||||
|
||||
function removeAllLiterals(): void;
|
||||
|
||||
const version: string;
|
||||
}
|
||||
|
||||
function jsep(val: string | jsep.Expression): jsep.Expression;
|
||||
|
||||
export = jsep;
|
||||
}
|
||||
Reference in New Issue
Block a user