同步操作将从 NULL/JavaScript-compiler 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
(function (factory) {if (typeof module === "object" && typeof module.exports === "object") {var v = factory(require, exports);if (v !== undefined) module.exports = v;}else if (typeof define === "function" && define.amd) {define(["require", "exports", "../tokenizer/tokenizer", "./statement", "./expression", "./terminal", "./exprParser"], factory);}})(function (require, exports) {"use strict";Object.defineProperty(exports, "__esModule", { value: true });const tokenizer_1 = require("../tokenizer/tokenizer");const statement_1 = require("./statement");const expression_1 = require("./expression");const terminal_1 = require("./terminal");const exprParser_1 = require("./exprParser");/*** 自顶部向下递归+lookahead一个token的parser* Program -> Stmts* Stmts -> Stmt Stmts | ε* Stmt -> AssignExpr | IfStmt | WhileStmt | Function | Block | ...* xxStmt -> Expr | Stmt | Terminal* Expr -> Terminal*/class Parser {//语法分析函数parse(sourceCode) {//从词法分析器拿到tokensthis.tokens = new tokenizer_1.Tokenizer(sourceCode).tokens;// 增加一个哨兵,用于判断结尾this.tokens.push({ type: 'eof', value: null });this.index = 0;this.lookahead = this.tokens[this.index++];const program = this.parseProgram();program.buildLexicalScope();return program;}//向前读一个token:封装index,避免危险操作read() {if (this.lookahead.type !== 'eof') {this.lookahead = this.tokens[this.index++];}}//校验token,并向前读一个match(value) {if (this.lookahead.value === value) {this.read();return value;}throw `syntax error @line ${this.lookahead.lineNo} : expect ${value} here but ${this.lookahead.value} found.`;}//校验类型(静态语言),并向前读一个matchType(type) {if (this.lookahead.type === type) {this.read();}throw 'syntax error';}//解析表达式parseExpr() {return new exprParser_1.expressionParser(this).exprParser();}/*** Stmts -> Stmt Stmts | ε*/parseStmts() {const stmts = [];while (this.lookahead.type !== 'eof' && this.lookahead.value !== '}') {stmts.push(this.parseStmt());}return stmts;}/*** Program -> Stmts*/parseProgram() {return new statement_1.Program(this.parseStmts());}/*** Stmt -> AssignExpr | IfStmt | WhileStmt | Function | Block | ...* AssignExpr -> var <id> = Expr* IfStmt -> if Expr Block else IfStmt | if Expr Block | Stmt*/parseStmt() {if (this.lookahead.type === 'id' || this.lookahead.type === 'number') {return this.parseExpr();}switch (this.lookahead.value) {case 'var':return this.parseDeclareStmt();case 'function':return this.parseFunctionStmt();case 'if':return this.parseIfStmt();case 'return':return this.parseReturnStmt();default:console.log(this.lookahead);throw `syntax error @line ${this.lookahead.lineNo} : not impl. ${this.lookahead.value}`;}}parseBlock() {this.match('{');const stmts = this.parseStmts();this.match('}');return new statement_1.Block(stmts);}/*** FunctionStmt -> function {id}(...ARGS) BLOCK*/parseFunctionStmt() {this.match('function');if (this.lookahead.type !== 'id') {throw 'syntax error';}const id = this.lookahead.value;this.match(id);this.match('(');const args = this.parseFuncArguments();this.match(')');const block = this.parseBlock();return new statement_1.Function(new terminal_1.Identifier(id), args, block);}/*** ReturnStmt -> return Expr*/parseReturnStmt() {this.match('return');const expr = this.parseExpr();return new statement_1.ReturnStmt(expr);}/*** Args -> <id> | <id>,Args | ε*/parseFuncArguments() {let list = [];if (this.lookahead.type === 'id') {const id = this.lookahead.value;this.match(id);list.push(new terminal_1.Identifier(id));if (this.lookahead.value === ',') {this.match(',');list = list.concat(this.parseFuncArguments());}}// else {// return []// }return new expression_1.Args(list, 'function');}/*** fn(args)函数调用的参数解析*/parseArguments() {let list = [];let expr = null;while ((expr = this.parseExpr())) {list.push(expr);}return new expression_1.Args(list);}/*** IfStmt -> if Expr Block | if Expr Block else IfStmt | if Expr Block else Block*/parseIfStmt() {this.match('if');const expr = this.parseExpr();const ifBlock = this.parseBlock();if (this.lookahead.value === 'else') {this.match('else');// @ts-ignoreif (this.lookahead.value === 'if') {const ifStmt = this.parseIfStmt();return new statement_1.IfStmt(expr, ifBlock, ifStmt);}else {const elseBlock = this.parseBlock();return new statement_1.IfStmt(expr, ifBlock, null, elseBlock);}}else {return new statement_1.IfStmt(expr, ifBlock);}}/*** DeclareStmt -> var id = expr*/parseDeclareStmt() {this.match('var');if (this.lookahead.type !== 'id') {throw 'syntax error';}const id = new terminal_1.Identifier(this.lookahead.value);this.match(this.lookahead.value);this.match('=');const right = this.parseExpr();return new statement_1.DeclareStmt(id, right);}/*** factor -> number | string | id*/parseFactor() {if (this.lookahead.type === 'number') {const value = this.match(this.lookahead.value);return new terminal_1.Numeral(value);}else if (this.lookahead.type === 'id') {const value = this.match(this.lookahead.value);if (this.lookahead.value === '(') {this.match('(');const args = this.parseArguments();this.match(')');return new expression_1.FunctionCallExpr(new terminal_1.Identifier(value), args);}else if (this.lookahead.value === '=') {this.match('=');const expr = this.parseExpr();return new expression_1.AssignExpr(new terminal_1.Identifier(value), expr);}return new terminal_1.Identifier(value);}else if (this.lookahead.type === 'string') {throw 'not impl.';}else {throw `syntax error, expect a factor but ${this.lookahead.value} found`;}}}exports.Parser = Parser;});//# sourceMappingURL=parser.js.map
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。