js实现简单计算器词法解析语法解析解释器,带可视化界面

本文主要是介绍js实现简单计算器词法解析语法解析解释器,带可视化界面,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

代码

Lexer是词法解析器

Parser是语法解析器

Interpreter 是ast解释器

可视化页面

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Lexer, Parser, and Interpreter Visualization</title><style>body {font-family: Arial, sans-serif;}#input-container {margin-bottom: 20px;}#lexer-output, #parser-output, #interpreter-output {border: 1px solid #ccc;padding: 10px;margin-bottom: 20px;}#lexer-output h2, #parser-output h2, #interpreter-output h2 {margin-top: 0;}#lexer-tokens, #parser-ast {list-style-type: none;padding: 0;}#lexer-tokens li {margin-bottom: 5px;}#parser-ast ul {padding-left: 20px;}</style>
</head>
<body><h1>Lexer, Parser, and Interpreter Visualization</h1><div id="input-container"><label for="input">Input Expression:</label><input type="text" id="input" placeholder="Enter expression..."><button onclick="processInput()">Process</button></div><div id="lexer-output"><h2>Lexer Output:</h2><ul id="lexer-tokens"></ul></div><div id="parser-output"><h2>Parser Output (Abstract Syntax Tree):</h2><pre id="parser-ast"></pre></div><div id="interpreter-output"><h2>Interpreter Output (Result):</h2><div id="interpreter-result"></div></div><script>function processInput() {const input = document.getElementById('input').value;// Lexerconst lexer = new Lexer(input);const lexerTokens = [];let token;while ((token = lexer.nextToken()) !== null) {lexerTokens.push(token);}displayLexerOutput(lexerTokens);// Parserconst parser = new Parser(new Lexer(input));const ast = parser.parse();displayParserOutput(ast);// Interpreterconst interpreter = new Interpreter();const result = interpreter.interpret(ast);displayInterpreterOutput(result);}function displayLexerOutput(tokens) {const lexerTokensList = document.getElementById('lexer-tokens');lexerTokensList.innerHTML = '';tokens.forEach(token => {const li = document.createElement('li');li.textContent = `${token.type}: ${token.value}`;lexerTokensList.appendChild(li);});}function displayParserOutput(ast) {const parserAST = document.getElementById('parser-ast');parserAST.textContent = JSON.stringify(ast, null, 2);}function displayInterpreterOutput(result) {const interpreterResult = document.getElementById('interpreter-result');interpreterResult.textContent = `Result: ${result}`;}class Lexer {constructor(input) {this.input = input;this.position = 0;}nextToken() {while (this.position < this.input.length && /\s/.test(this.input[this.position])) {this.position++;}if (this.position >= this.input.length) {return null;}let currentChar = this.input[this.position];if (/\d/.test(currentChar)) {let number = '';while (/\d/.test(currentChar) && this.position < this.input.length) {number += currentChar;this.position++;currentChar = this.input[this.position];}return { type: 'NUMBER', value: number };}if (currentChar === '+') {this.position++;return { type: 'PLUS', value: '+' };}if (currentChar === '-') {this.position++;return { type: 'MINUS', value: '-' };}if (currentChar === '*') {this.position++;return { type: 'STAR', value: '*' };}if (currentChar === '/') {this.position++;return { type: 'SLASH', value: '/' };}if (currentChar === '(') {this.position++;return { type: 'LPAREN', value: '(' };}if (currentChar === ')') {this.position++;return { type: 'RPAREN', value: ')' };}throw new Error(`Unknown character: ${currentChar}`);}}class Parser {constructor(lexer) {this.lexer = lexer;this.currentToken = this.lexer.nextToken();}eat(tokenType) {if (this.currentToken && this.currentToken.type === tokenType) {this.currentToken = this.lexer.nextToken();} else {throw new Error(`Expected token type ${tokenType} but got ${this.currentToken ? this.currentToken.type : 'null'}`);}}factor() {let token = this.currentToken;if (token.type === 'NUMBER') {this.eat('NUMBER');return { type: 'Literal', value: parseInt(token.value, 10) };} else if (token.type === 'LPAREN') {this.eat('LPAREN');let node = this.expr();this.eat('RPAREN');return node;} else {throw new Error(`Unexpected token: ${token.type}`);}}term() {let node = this.factor();while (this.currentToken && (this.currentToken.type === 'STAR' || this.currentToken.type === 'SLASH')) {let token = this.currentToken;if (token.type === 'STAR') {this.eat('STAR');} else if (token.type === 'SLASH') {this.eat('SLASH');}node = { type: 'BinaryExpression', operator: token.value, left: node, right: this.factor() };}return node;}expr() {let node = this.term();while (this.currentToken && (this.currentToken.type === 'PLUS' || this.currentToken.type === 'MINUS')) {let token = this.currentToken;if (token.type === 'PLUS') {this.eat('PLUS');} else if (token.type === 'MINUS') {this.eat('MINUS');}node = { type: 'BinaryExpression', operator: token.value, left: node,right: this.term() };}return node;}parse() {return this.expr();}}class Interpreter {interpret(node) {if (node.type === 'Literal') {return node.value;} else if (node.type === 'BinaryExpression') {const leftValue = this.interpret(node.left);const rightValue = this.interpret(node.right);switch (node.operator) {case '+':return leftValue + rightValue;case '-':return leftValue - rightValue;case '*':return leftValue * rightValue;case '/':if (rightValue === 0) {throw new Error('Division by zero');}return leftValue / rightValue;default:throw new Error(`Unknown operator: ${node.operator}`);}} else {throw new Error(`Unknown node type: ${node.type}`);}}}</script>
</body>
</html>

这篇关于js实现简单计算器词法解析语法解析解释器,带可视化界面的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1051248

相关文章

MySQL中查找重复值的实现

《MySQL中查找重复值的实现》查找重复值是一项常见需求,比如在数据清理、数据分析、数据质量检查等场景下,我们常常需要找出表中某列或多列的重复值,具有一定的参考价值,感兴趣的可以了解一下... 目录技术背景实现步骤方法一:使用GROUP BY和HAVING子句方法二:仅返回重复值方法三:返回完整记录方法四:

IDEA中新建/切换Git分支的实现步骤

《IDEA中新建/切换Git分支的实现步骤》本文主要介绍了IDEA中新建/切换Git分支的实现步骤,通过菜单创建新分支并选择是否切换,创建后在Git详情或右键Checkout中切换分支,感兴趣的可以了... 前提:项目已被Git托管1、点击上方栏Git->NewBrancjsh...2、输入新的分支的

Python实现对阿里云OSS对象存储的操作详解

《Python实现对阿里云OSS对象存储的操作详解》这篇文章主要为大家详细介绍了Python实现对阿里云OSS对象存储的操作相关知识,包括连接,上传,下载,列举等功能,感兴趣的小伙伴可以了解下... 目录一、直接使用代码二、详细使用1. 环境准备2. 初始化配置3. bucket配置创建4. 文件上传到os

深度解析Java DTO(最新推荐)

《深度解析JavaDTO(最新推荐)》DTO(DataTransferObject)是一种用于在不同层(如Controller层、Service层)之间传输数据的对象设计模式,其核心目的是封装数据,... 目录一、什么是DTO?DTO的核心特点:二、为什么需要DTO?(对比Entity)三、实际应用场景解析

关于集合与数组转换实现方法

《关于集合与数组转换实现方法》:本文主要介绍关于集合与数组转换实现方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、Arrays.asList()1.1、方法作用1.2、内部实现1.3、修改元素的影响1.4、注意事项2、list.toArray()2.1、方

深度解析Java项目中包和包之间的联系

《深度解析Java项目中包和包之间的联系》文章浏览阅读850次,点赞13次,收藏8次。本文详细介绍了Java分层架构中的几个关键包:DTO、Controller、Service和Mapper。_jav... 目录前言一、各大包1.DTO1.1、DTO的核心用途1.2. DTO与实体类(Entity)的区别1

Java中的雪花算法Snowflake解析与实践技巧

《Java中的雪花算法Snowflake解析与实践技巧》本文解析了雪花算法的原理、Java实现及生产实践,涵盖ID结构、位运算技巧、时钟回拨处理、WorkerId分配等关键点,并探讨了百度UidGen... 目录一、雪花算法核心原理1.1 算法起源1.2 ID结构详解1.3 核心特性二、Java实现解析2.

使用Python实现可恢复式多线程下载器

《使用Python实现可恢复式多线程下载器》在数字时代,大文件下载已成为日常操作,本文将手把手教你用Python打造专业级下载器,实现断点续传,多线程加速,速度限制等功能,感兴趣的小伙伴可以了解下... 目录一、智能续传:从崩溃边缘抢救进度二、多线程加速:榨干网络带宽三、速度控制:做网络的好邻居四、终端交互

java实现docker镜像上传到harbor仓库的方式

《java实现docker镜像上传到harbor仓库的方式》:本文主要介绍java实现docker镜像上传到harbor仓库的方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录1. 前 言2. 编写工具类2.1 引入依赖包2.2 使用当前服务器的docker环境推送镜像2.2

C++20管道运算符的实现示例

《C++20管道运算符的实现示例》本文简要介绍C++20管道运算符的使用与实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录标准库的管道运算符使用自己实现类似的管道运算符我们不打算介绍太多,因为它实际属于c++20最为重要的