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

相关文章

SpringBoot3实现Gzip压缩优化的技术指南

《SpringBoot3实现Gzip压缩优化的技术指南》随着Web应用的用户量和数据量增加,网络带宽和页面加载速度逐渐成为瓶颈,为了减少数据传输量,提高用户体验,我们可以使用Gzip压缩HTTP响应,... 目录1、简述2、配置2.1 添加依赖2.2 配置 Gzip 压缩3、服务端应用4、前端应用4.1 N

SpringBoot实现数据库读写分离的3种方法小结

《SpringBoot实现数据库读写分离的3种方法小结》为了提高系统的读写性能和可用性,读写分离是一种经典的数据库架构模式,在SpringBoot应用中,有多种方式可以实现数据库读写分离,本文将介绍三... 目录一、数据库读写分离概述二、方案一:基于AbstractRoutingDataSource实现动态

Python FastAPI+Celery+RabbitMQ实现分布式图片水印处理系统

《PythonFastAPI+Celery+RabbitMQ实现分布式图片水印处理系统》这篇文章主要为大家详细介绍了PythonFastAPI如何结合Celery以及RabbitMQ实现简单的分布式... 实现思路FastAPI 服务器Celery 任务队列RabbitMQ 作为消息代理定时任务处理完整

使用Jackson进行JSON生成与解析的新手指南

《使用Jackson进行JSON生成与解析的新手指南》这篇文章主要为大家详细介绍了如何使用Jackson进行JSON生成与解析处理,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 核心依赖2. 基础用法2.1 对象转 jsON(序列化)2.2 JSON 转对象(反序列化)3.

Springboot @Autowired和@Resource的区别解析

《Springboot@Autowired和@Resource的区别解析》@Resource是JDK提供的注解,只是Spring在实现上提供了这个注解的功能支持,本文给大家介绍Springboot@... 目录【一】定义【1】@Autowired【2】@Resource【二】区别【1】包含的属性不同【2】@

Java枚举类实现Key-Value映射的多种实现方式

《Java枚举类实现Key-Value映射的多种实现方式》在Java开发中,枚举(Enum)是一种特殊的类,本文将详细介绍Java枚举类实现key-value映射的多种方式,有需要的小伙伴可以根据需要... 目录前言一、基础实现方式1.1 为枚举添加属性和构造方法二、http://www.cppcns.co

使用Python实现快速搭建本地HTTP服务器

《使用Python实现快速搭建本地HTTP服务器》:本文主要介绍如何使用Python快速搭建本地HTTP服务器,轻松实现一键HTTP文件共享,同时结合二维码技术,让访问更简单,感兴趣的小伙伴可以了... 目录1. 概述2. 快速搭建 HTTP 文件共享服务2.1 核心思路2.2 代码实现2.3 代码解读3.

MySQL双主搭建+keepalived高可用的实现

《MySQL双主搭建+keepalived高可用的实现》本文主要介绍了MySQL双主搭建+keepalived高可用的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,... 目录一、测试环境准备二、主从搭建1.创建复制用户2.创建复制关系3.开启复制,确认复制是否成功4.同

Java实现文件图片的预览和下载功能

《Java实现文件图片的预览和下载功能》这篇文章主要为大家详细介绍了如何使用Java实现文件图片的预览和下载功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... Java实现文件(图片)的预览和下载 @ApiOperation("访问文件") @GetMapping("

用js控制视频播放进度基本示例代码

《用js控制视频播放进度基本示例代码》写前端的时候,很多的时候是需要支持要网页视频播放的功能,下面这篇文章主要给大家介绍了关于用js控制视频播放进度的相关资料,文中通过代码介绍的非常详细,需要的朋友可... 目录前言html部分:JavaScript部分:注意:总结前言在javascript中控制视频播放