Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@jeefo/parser

Package Overview
Dependencies
Maintainers
1
Versions
28
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@jeefo/parser - npm Package Compare versions

Comparing version 0.0.1 to 0.0.2

ast_node_definition.js

414

index.js
/* -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
* File Name : index.js
* Created at : 2019-01-23
* Updated at : 2019-03-09
* Updated at : 2019-09-08
* Author : jeefo
* Purpose :
* Description :
_._._._._._._._._._._._._._._._._._._._._.*/
* Reference :
.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.*/
// ignore:start
"use strict";
/* globals */
/* exported */
/* globals*/
/* exported*/
// ignore:end
const State = require("./src/state"),
assign = require("jeefo_utils/object/assign"),
UnexpectedTokenException = require("./src/unexpected_token_exception");
const JeefoTokenizer = require("@jeefo/tokenizer");
const assign = require("@jeefo/utils/object/assign");
const for_each = require("@jeefo/utils/object/for_each");
const State = require("./src/state");
const I_AST_Node = require("./src/i_ast_node");
const AST_Node_Table = require("./src/ast_node_table");
const AST_Node_Definition = require("./src/ast_node_definition");
const UnexpectedTokenException = require("./src/unexpected_token_exception");
const TERMINATOR_PRECEDENCE = 0;
const TERMINATOR_PRECEDENCE = 0;
const object_define_property = Object.defineProperty;
class JeefoParser {
/**
static get JeefoTokenizer () { return JeefoTokenizer; }
static get I_AST_Node () { return I_AST_Node; }
static get AST_Node_Table () { return AST_Node_Table; }
static get AST_Node_Definition () { return AST_Node_Definition; }
static get UnexpectedTokenException () {
return UnexpectedTokenException;
}
/**
* @Validators
* @param: language (String)
* @param: tokenizer (JeefoTokenizer)
* @param: symbol_table (JeefoSymbolTable)
*/
constructor (language, tokenizer, symbol_table) {
this.language = language;
this.tokenizer = tokenizer;
this.symbol_table = symbol_table;
* @param: language (String)
* @param: tokenizer (JeefoTokenizer)
* @param: ast_node_table (AST_Node_Table)
*/
constructor (language, tokenizer, ast_node_table) {
if (typeof language !== "string") {
throw new TypeError("Invalid argument: language");
}
if (! (tokenizer instanceof JeefoTokenizer)) {
throw new TypeError("Invalid argument: tokenizer");
}
if (! (ast_node_table instanceof AST_Node_Table)) {
throw new TypeError("Invalid argument: ast_node_table");
}
this.is_terminated = null;
this.current_symbol = null;
this.previous_symbols = null;
this.language = language;
this.tokenizer = tokenizer;
this.ast_node_table = ast_node_table;
this.next_token = null;
this.next_symbol_definition = null;
this.debug = false;
this.prev_node = null;
this.ending_index = 0;
this.is_terminated = null;
this.previous_nodes = null;
this.next_token = null;
this.next_node_definition = null;
this.state = new State();
this.suffixes = [];
this.context_stack = [];
this.current_state = this.state.default;
}
prepare_next_symbol_definition () {
this.next_token = this.tokenizer.get_next_token();
let onpreparation = null;
object_define_property(this, "onpreparation", {
get () { return onpreparation; },
set (value) {
if (typeof value !== "function") {
throw new TypeError(
"Assigned onpreparation is not a function"
);
}
onpreparation = value;
}
});
}
if (this.next_token) {
this.next_symbol_definition = this.symbol_table.get_symbol_definition(this.next_token, this);
if (typeof this.onpreparation === "function") {
look_ahead (throw_end_of_stream) {
const {
next_token : current_token,
current_state : prev_state,
next_node_definition : current_node_def,
prev_node, previous_nodes
} = this;
this.tokenizer.streamer.cursor.save();
this.prev_node = null;
this.current_state = null;
this.previous_nodes = [];
this.prepare_next_node_definition(throw_end_of_stream);
const next_token = this.next_token;
this.tokenizer.streamer.cursor.rollback();
this.prev_node = prev_node;
this.next_token = current_token;
this.current_state = prev_state;
this.previous_nodes = previous_nodes;
this.next_node_definition = current_node_def;
return next_token;
}
prepare_next_node_definition (throw_end_of_stream) {
this.next_token = this.tokenizer.get_next_token();
if (this.next_token) {
// Only dev mode
if (this.next_token) {
this.next_token.id = this.next_token.id;
this.next_token.priority = this.next_token.priority;
}
// Only dev mode
this.next_node_definition = this.ast_node_table.find(
this.next_token, this
);
if (this.onpreparation) {
this.onpreparation(this);
if (this.is_terminated || ! this.next_token) {
this.next_node_definition = null;
}
}
} else {
this.next_symbol_definition = null;
}
}
} else if (throw_end_of_stream) {
this.throw_unexpected_end_of_stream();
} else {
this.next_node_definition = null;
}
}
prepare_next_state (state_name, throw_end_of_stream) {
this.is_terminated = false;
this.current_symbol = null;
this.previous_symbols = [];
this.prev_node = null;
this.is_terminated = false;
this.previous_nodes = [];
this.next_node_definition = null;
this.current_state = state_name ? this.state.get_value(state_name) : this.state.default;
this.prepare_next_symbol_definition();
if (state_name) {
this.current_state = this.state.get_value(state_name);
} else {
this.current_state = this.state.default;
}
this.prepare_next_node_definition(throw_end_of_stream);
}
if (throw_end_of_stream && this.next_token === null) {
this.throw_unexpected_end_of_stream();
generate_next_node () {
if (! this.next_node_definition) {
this.throw_unexpected_token("AST_Node_Definition is not found");
}
return this.next_node_definition.generate_new_node(this);
}
change_state (state_name) {
this.current_state = this.state.get_value(state_name);
this.next_symbol_definition = this.symbol_table.get_symbol_definition(this.next_token, this);
change_state (state_name, set_prev_state, find_new_node = true) {
if (set_prev_state !== undefined) {
console.log(set_prev_state);
throw new Error("Deprecated");
}
if (set_prev_state) {
this.prev_state = this.current_state;
}
this.current_state = this.state.get_value(state_name);
if (find_new_node) {
this.next_node_definition = this.ast_node_table.find(
this.next_token, this
);
}
}
terminate (symbol) {
if (symbol === undefined) {
throw new Error("Undefined termination");
terminate (node) {
if (node === undefined) {
if (this.debug) { console.log(this); }
throw new Error("argument must be AST_Node object.");
}
this.is_terminated = true;
this.next_token = null;
this.next_symbol_definition = null;
assign(this.tokenizer.streamer.cursor, symbol.end);
}
this.is_terminated = true;
this.next_token = null;
this.next_node_definition = null;
assign(this.tokenizer.streamer.cursor.position, node.end);
}
get_next_symbol (left_precedence) {
if (typeof left_precedence !== "number") {
throw new Error("Invalid left precedence");
}
parse_next_node (left_precedence) {
if (typeof left_precedence !== "number") {
if (this.debug) { console.log(this); }
throw new Error("Invalid left precedence");
}
while (this.next_token) {
if (this.next_symbol_definition === null) {
this.throw_unexpected_token();
while (this.next_token) {
if (this.next_node_definition === null) {
if (this.throw_not_found) {
this.throw_unexpected_token(
"AST_Node_Definition is not found"
);
}
break;
}
if (this.next_symbol_definition.precedence <= left_precedence) {
if (this.next_node_definition.precedence <= left_precedence) {
break;
}
const current_token = this.next_token;
this.current_symbol = this.next_symbol_definition.generate_new_symbol(this);
this.previous_symbols.push(this.current_symbol);
this.ending_index = this.next_token.end.index;
this.set_prev_node(this.generate_next_node());
if (current_token === this.next_token) {
this.prepare_next_symbol_definition();
// Debug only
if ([null, undefined].includes(this.current_state)) {
this.throw_unexpected_token("Invalid current_state");
}
}
// Debug only
return this.current_symbol;
}
if (this.next_token) {
if (this.next_token.end.index === this.ending_index) {
this.prepare_next_node_definition();
} else {
this.next_node_definition = this.ast_node_table.find(
this.next_token, this
);
}
}
}
parse (script, tab_size) {
const symbols = [];
this.tokenizer.init(script, tab_size);
return this.prev_node;
}
parse (script, tab_size) {
const nodes = [];
this.context_stack = [];
this.tokenizer.init(script, tab_size);
this.prepare_next_state();
while (this.next_token) {
const symbol = this.get_next_symbol(TERMINATOR_PRECEDENCE);
if (symbol) {
symbols.push(symbol);
while (this.next_token) {
const node = this.parse_next_node(TERMINATOR_PRECEDENCE);
if (node) {
nodes.push(node);
} else {
this.throw_unexpected_token();
this.throw_unexpected_token("AST_Node is not found.");
}
this.prepare_next_state();
}
}
return symbols;
}
return nodes;
}
is_next_node (id) {
if (this.next_node_definition) {
return this.next_node_definition.id === id;
}
return false;
}
set_prev_node (prev_node) {
this.prev_node = prev_node;
this.previous_nodes.push(prev_node);
}
get_state_name (state) {
const { values } = this.state;
return Object.keys(values).find(state_name => {
return values[state_name] === state;
});
}
get_state_value (state_name) {
return this.state.get_value(state_name);
}
get_current_state_name () {
return this.get_state_name(this.current_state);
}
end (node) {
this.ending_index = node.end.index;
}
refine (state_name, input_node) {
this.change_state(state_name, undefined);
if (! this.next_node_definition) {
this.throw_unexpected_token(
`Unexpected state to refine: ${ state_name }`,
input_node
);
}
const Node = this.next_node_definition.Node;
if (! this.next_node_definition.refine) {
this.throw_unexpected_token(
`refine method is not implemented in: ${
Node.prototype.constructor.name
}`, input_node
);
}
const node = new Node();
this.next_node_definition.refine(node, input_node, this);
return node;
}
is_reserved_word (value) {
return this.ast_node_table.reserved_words[value] !== undefined;
}
expect (expectation, condition) {
if (! condition(this)) {
this.throw_unexpected_token(`Expected ${ expectation } instead saw: ${ this.next_token.value }`);
const { streamer } = this.tokenizer;
this.throw_unexpected_token(
`Expected ${ expectation } instead saw: ${
streamer.substring_from_token(this.next_token)
}`
);
}
}
throw_unexpected_token (error_message) {
throw new UnexpectedTokenException(this, error_message);
}
throw_unexpected_token (error_message, token) {
if (token) {
this.next_token = token;
}
if (this.debug) { console.log(this); }
throw new UnexpectedTokenException(this, error_message);
}
throw_unexpected_end_of_stream () {
throw new SyntaxError("Unexpected end of stream");
}
throw_unexpected_refine (refining_node, error_node) {
this.throw_unexpected_token(
`Unexpected '${ error_node.constructor.name }' refine in: ${
refining_node.constructor.name
}`, error_node
);
}
throw_unexpected_end_of_stream () {
if (this.debug) { console.log(this); }
throw new SyntaxError("Unexpected end of stream");
}
clone (name) {
name = name || this.name;
const tokenizer = new JeefoTokenizer();
const ast_node_table = new AST_Node_Table();
this.tokenizer.token_definitions.forEach(td => {
tokenizer.register({
id : td.Token.prototype.id,
priority : td.Token.prototype.priority,
is : td.is,
initialize : td.initialize,
});
});
const { reserved_words, node_definitions } = this.ast_node_table;
const defs = [];
for_each(reserved_words, (word, node_def) => {
const def = defs.find(d => d.node_def === node_def);
if (def) {
def.words.push(word);
} else {
defs.push({ words: [word], node_def });
}
});
defs.forEach(def => {
ast_node_table.register_reserved_words(def.words, def.node_def);
});
ast_node_table.node_definitions = node_definitions.map(d => d.clone());
const clone = new JeefoParser(name, tokenizer, ast_node_table);
Object.assign(clone.state.values, this.state.values);
clone.state.default = this.state.default;
if (this.onpreparation) {
clone.onpreparation = this.onpreparation;
}
return clone;
}
}
JeefoParser.prototype.onpreparation = null;
module.exports = JeefoParser;
{
"name": "@jeefo/parser",
"version": "0.0.1",
"description": "jeefo parser",
"author": {
"name": "je3f0o",
"email": "je3f0o@gmail.com"
},
"homepage": "https://github.com/je3f0o/jeefo_parser",
"license": "MIT",
"copyright": "2019",
"main": "index.js",
"scripts": {
"test": "./node_modules/mocha/bin/mocha \"specs/**/*_specs.js\""
},
"repository": {
"type": "git",
"url": "https://github.com/je3f0o/jeefo_parser.git"
},
"keywords": [
"jeefo",
"parser"
],
"devDependencies": {
"expect.js": "^0.3.1",
"mocha": "^3.5.0"
},
"dependencies": {
"jeefo_command": "^0.0.20",
"jeefo_tokenizer": "^0.0.37",
"jeefo_utils": "^0.0.5"
}
}
"name": "@jeefo/parser",
"version": "0.0.2",
"description": "A library for parsing AST for any language.",
"author": {
"name": "je3f0o",
"email": "je3f0o@gmail.com"
},
"homepage": "https://github.com/je3f0o/jeefo_parser",
"license": "MIT",
"copyright": "2019",
"main": "index.js",
"scripts": {
"test": "./node_modules/mocha/bin/mocha \"specs/**/*_specs.js\"",
"publish": "npx @jeefo/publish"
},
"repository": {
"type": "git",
"url": "https://github.com/je3f0o/jeefo_parser.git"
},
"keywords": [
"jeefo",
"je3f0o",
"parser"
],
"devDependencies": {
"@jeefo/publish": "0.0.22"
},
"dependencies": {}
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc