源码下载:https://files.cnblogs.com/files/heyang78/basicInterpreter-20200529-1.rar

脚本:

count=
print(count)
count=
print(count)
print(cnt)
print("Hello!Interpreter!")

说明:

count=10      赋值语句,变量count赋值为10,变量count不需定义
print(count)   打印变量count里的值
count=20      赋值语句,变量count赋值为20
print(count)  打印变量count里的值
print(cnt)    打印变量cnt里的值
print("Hello!Interpreter!") 打印字符串"Hello!Interpreter!"

执行结果:

原文=count= print(count) count= print(count) print(cnt) print("Hello!Interpreter!")
Index Type No Text Type Desc
------------------------------------------------------------------------------------
count Variable
= =
Number
print Function
( (
count Variable
) )
count Variable
= =
Number
print Function
( (
count Variable
) )
print Function
( (
cnt Variable
) )
print Function
( (
"Hello!Interpreter!" String
) ) 执行结果: Variable:'cnt' was not assigned.
"Hello!Interpreter!"

核心程序:

Token类:

package com.heyang;

public class Token {
public static final int TYPE_OPEN_PARENTHESIS=0; // (
public static final int TYPE_CLOSE_PARENTHESIS=1; // (
public static final int TYPE_EQUAL=2; // =
public static final int TYPE_NUMBER=4; // \d+
public static final int TYPE_STRING=5; // \w+
public static final int TYPE_VARIABLE=6; // Variable
public static final int TYPE_FUNCTION=7; // Function private int type;
private String text;
private int index;// Used to remember location public Token(char c,int type) {
this.text=String.valueOf(c);
this.type=type;
} public Token(String word,int type) {
this.text=word;
this.type=type;
} public String toString() {
return String.format("token(text=%s,type=%s,index=%d)", text,getTypeStr(),index);
} public String getTypeStr() {
if(type==TYPE_OPEN_PARENTHESIS) {
return "(";
}else if(type==TYPE_CLOSE_PARENTHESIS) {
return ")";
}else if(type==TYPE_EQUAL) {
return "=";
}else if(type==TYPE_NUMBER) {
return "Number";
}else if(type==TYPE_STRING) {
return "String";
}else if(type==TYPE_VARIABLE) {
return "Variable";
}else if(type==TYPE_FUNCTION) {
return "Function";
} return null;
} public int getType() {
return type;
} public void setType(int type) {
this.type = type;
} public String getText() {
return text;
} public void setText(String text) {
this.text = text;
} public int getIndex() {
return index;
} public void setIndex(int index) {
this.index = index;
}
}

Lexer类:

package com.heyang;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.regex.Pattern; /**
* Parse json string to tokens
* @author Heyang
*
*/
public class Lexer {
private List<Token> tokens; public Lexer(String jsonTxt) {
tokens = new ArrayList<Token>(); String swallowed = "";
for (int i = 0; i < jsonTxt.length(); i++) {
char c = jsonTxt.charAt(i); if (Character.isWhitespace(c)) {
addTextToList(swallowed);
swallowed="";
continue;
} else if (c == '(') {
addTextToList(swallowed);
swallowed=""; tokens.add(new Token(c, Token.TYPE_OPEN_PARENTHESIS));
} else if (c == ')') {
addTextToList(swallowed);
swallowed=""; tokens.add(new Token(c, Token.TYPE_CLOSE_PARENTHESIS));
} else if (c == '=') {
addTextToList(swallowed);
swallowed=""; tokens.add(new Token(c, Token.TYPE_EQUAL));
} else if(c == '\"') {
addTextToList(swallowed);
swallowed=""; int idx=i+1; while(idx<jsonTxt.length()) {
char cEnd = jsonTxt.charAt(idx); if (cEnd == '\"') {
break;
} idx++;
} String sub=jsonTxt.substring(i, idx+1);
tokens.add(new Token(sub, Token.TYPE_STRING));
i=idx;
} else {
swallowed += c;
}
} setTokenIndexes();
} private void addTextToList(String text) {
if(isFunction(text)) {
tokens.add(new Token(text, Token.TYPE_FUNCTION));
}else if(isNumber(text)) {
tokens.add(new Token(text, Token.TYPE_NUMBER));
}else if(isVarable(text)) {
tokens.add(new Token(text, Token.TYPE_VARIABLE));
}
} private boolean isFunction(String text) {
if("print".equalsIgnoreCase(text)) {
return true;
} return false;
} private boolean isNumber(String code) {
final String patternStr = "\\d+";
return Pattern.matches(patternStr, code);
} private boolean isVarable(String code) {
final String patternStr = "([a-zA-Z_])\\w*";
return Pattern.matches(patternStr, code);
} public void printTokens() {
final String continuousStar = createRepeatedStr("-", 84);
final String layout = "%-20s %-20s %-20s %-20s %s";
StringBuilder sb = new StringBuilder(); sb.append(String.format(layout, "Index", "Type No","Text","Type Desc","\n"));
sb.append(continuousStar + "\n");
int index=0;
for(Token token:tokens) {
sb.append(String.format(layout, String.valueOf(index),String.valueOf(token.getType()), token.getText(),token.getTypeStr(),"\n"));
index++;
} System.out.println(sb.toString());
} private static String createRepeatedStr(String seed, int n) {
return String.join("", Collections.nCopies(n, seed));
} public void setTokenIndexes() {
int idx = 0;
for (Token t : tokens) {
idx++;
t.setIndex(idx);
}
} public String getCompactJsonTxt() {
StringBuilder sb=new StringBuilder(); for (Token t : tokens) {
sb.append(t.getText());
} return sb.toString();
} public List<Token> getTokenList() {
return tokens;
}
}

Interpreter类:

package com.heyang;

import java.util.HashMap;
import java.util.List;
import java.util.Map; public class Interpreter {
private List<Token> tokens;
private int tokenIdx; public Interpreter(List<Token> tokens) throws Exception{
this.tokens=tokens;
this.tokenIdx=0; execute();
} private void execute() throws Exception{
Map<String,Integer> varmap=new HashMap<String,Integer>();
Token token;
for(;;) {
token=fetchToken();
if(token==null) {
return;
} if(token.getType()==Token.TYPE_VARIABLE) {
String varibleName=token.getText(); token=fetchToken();
if(token.getType()==Token.TYPE_EQUAL) {
token=fetchToken(); if(token.getType()==Token.TYPE_NUMBER) {
int variableValue=Integer.parseInt(token.getText()); // 赋值核心语句
varmap.put(varibleName, variableValue);
}
}else {
throw new Exception("Expected:'=' actual:"+token.getText()+" "+token);
}
}else if(token.getType()==Token.TYPE_FUNCTION) {
String functionName=token.getText(); if("print".equalsIgnoreCase(functionName)) {
token=fetchToken();
if(token.getType()!=Token.TYPE_OPEN_PARENTHESIS) {
throw new Exception("Expected:'(' actual:"+token.getText()+" "+token);
} token=fetchToken();
if(token.getType()==Token.TYPE_STRING) {
// 打印字符串
String str=token.getText();
System.out.println(str);
}else if(token.getType()==Token.TYPE_VARIABLE) {
String varibleName=token.getText(); // 打印变量
if(varmap.containsKey(varibleName)) {
int value=varmap.get(varibleName);
System.out.println(value);
}else {
System.out.println("Variable:'"+varibleName+"' was not assigned.");
}
}
}
}
}
} private Token fetchToken() {
if(tokenIdx>=tokens.size()) {
return null;
}else {
Token t=tokens.get(tokenIdx);
tokenIdx++;
return t;
}
} private void returnToken() {
if(tokenIdx>0) {
tokenIdx--;
}
}
}

整合:

package com.heyang;

import com.heyang.util.BracketChecker;
import com.heyang.util.CommonUtil;
import com.heyang.util.Renderer; public class EntryPoint {
public static void main(String[] args) {
try {
// Read context from file
String text=CommonUtil.readTextFromFile("C:\\hy\\files\\basic\\01.basic");
System.out.println("原文="+text); // Is brackets balanced
BracketChecker checker=new BracketChecker();
boolean isBalanced=checker.isBalanced(text);
if(isBalanced==false) {
System.out.println(Renderer.paintBrown(checker.getErrMsg()));
return;
} // lex text to tokens
Lexer lex=new Lexer(text);
lex.printTokens(); // Execute
System.out.println("执行结果:\n");
new Interpreter(lex.getTokenList());
}catch(Exception ex) {
System.out.println(Renderer.paintBrown(ex.getMessage()));
ex.printStackTrace();
}
}
}

感慨:在《Java编程艺术》的指引下,解释器的第一步踏出了。

--2020年5月29日--

BasicInterpreter1.00 运行简单Basic脚本 打印变量及字符串的更多相关文章

  1. 自编Basic脚本 用BasicIntepreter执行 打印九九乘法表

    源码下载:https://files.cnblogs.com/files/heyang78/BasicInterpreter2-20200601-2.rar 用编程语言打印九九乘法表不难,用自编解释器 ...

  2. Shell基础(一):Shell基础应用、简单Shell脚本的设计、使用Shell变量、变量的扩展应用

    一.Shell基础应用 目标: 本案例要求熟悉Linux Shell环境的特点,主要练习以下操作: 1> 切换用户的Shell环境       2> 练习命令历史.命令别名       3 ...

  3. Ant 脚本打印系统属性变量、ant内置属性

    Ant 脚本打印系统属性变量.ant内置属性 作用 编写ant脚本的时候,经常会引用到系统属性,本脚本用于打印系统常用属性(System.getProperties)与环境变量(Environment ...

  4. Linux计划任务 定时任务 Crond 配置详解 crond计划任务调试 sh -x 详解 JAVA脚本环境变量定义

    一.Crond 是什么?(概述) crontab 是一款linux系统中的定时任务软件用于实现无人值守或后台定期执行及循环执行任务的脚本程序,在企业中使用的非常广泛.     现在开始学习linux计 ...

  5. Linux简单Shell脚本监控MySQL、Apache Web和磁盘空间

    Linux简单Shell脚本监控MySQL.Apache Web和磁盘空间 1. 目的或任务 当MySQL数据库.Apache Web服务器停止运行时,重新启动运行,并发送邮件通知: 当服务器磁盘的空 ...

  6. shell脚本之变量与状态码

    目录: 前言 如何创建一个脚本 脚本调试 变量相关 变量的命令规则 bash中变量的种类 本地变量 环境变量 只读和位置变量 位置变量 查询变量 进程的退出状态与状态码 前言 在linux管理中,sh ...

  7. 使用Windows任务计划程序运行Windows PowerShell脚本

    创建计划任务以运行PowerShell脚本 我需要创建一个计划任务来运行Windows PowerShell脚本的第一件事是我将执行的命令行.找到这个的简单方法是使用Run 命令.有时,我需要知道什么 ...

  8. Tensorflow之调试(Debug)及打印变量

    参考资料:https://wookayin.github.io/tensorflow-talk-debugging 几种常用方法: 1.通过Session.run()获取变量的值 2.利用Tensor ...

  9. 【三支火把】--- shell脚本中变量的类型及作用域

    一直对shell脚本有一种特殊的感觉,因此花了一段时间学习,本人擅长C语言编程,深受C语言荼毒,在学习其他任何类似于编程语言的东东的时候,都会不自觉的与C进行对比,因此对于shell中的变量的作用域一 ...

随机推荐

  1. Docker 搭建 Keycloak

    Docker 搭建 Keycloak 命令 需要创建好数据库,启动容器指定数据库信息 # KEYCLOAK_USER 用户名 # KEYCLOAK_PASSWORD 密码 # DB_ADDR 数据库地 ...

  2. linux7手动添加systemctl启动程序

    1.路径 [root@angrymushrooms01 system]# pwd /usr/lib/systemd/system 2.脚本内容 vim xxx.service ------------ ...

  3. Elasticsearch第二篇:基本概念和基础操作

    上一篇文章,我们已经是在Windows10 上搭建了 Elasticsearch 环境已经安装了相关的插件,现在我们就可以像操作webapi一样简单的操作 ElasticSearch 了,有园友说可以 ...

  4. Win10系统Jmeter+maven+Jenkins接口自动化环境搭建(一)

    Jmeter+maven+Jenkins实现接口自动化,需要使用idea或eclipse配置maven项目,这里我使用的是idea.具体步骤如下: 1.安装jmeter+jdk jmeter安装之前需 ...

  5. 运用cookie实现记住密码自动登陆:

    苦命的程序员:只有博客才能了解我的路!!! 废话不多说:直接上代码: 1.首先在现在登录的页面上来获取cookie的所有: 2.在验证页面来设置clookie的用户名和密码还有是否是自动登录: 到此就 ...

  6. python设计模式之适配器模式

    python设计模式之适配器模式 结构型设计模式一个系统中不同实体(比如,类和对象)之间的关系,关注的是提供一种简单的对象组合方式来创造功能. 适配器模式( Adapter pattern)是一种结构 ...

  7. day1 计算机的组成

    1.计算机,是用于高速计算的电子机器,具有数值计算, 逻辑判断,储存记忆的功能. 2.计算机由硬件系统和软件系统组成构成. 3.计算机中所有的运行程序都是在内存中进行的,暂时存放在CPU中的运算数据 ...

  8. Core + Vue 后台管理基础框架9——统一日志

    1.背景 前阵子有园友留言,提到日志相关的东西,同时,最近圈子里也有提到日志这个东西.一个充分.集中的统一日志平台还是很有必要的,否则系统出问题了只能靠猜或者干瞪眼.何谓充分,日志记录满足最低要求.出 ...

  9. 输入url后的加载过程~

    1)查找域名对应的IP地址: 2)建立连接(TCP的三次握手): 3)构建网页: 4)断开连接(TCP的四次挥手): TCP的三次握手:为了准确无误的把数据送到目标处,TCP协议采用了三次握手策略,用 ...

  10. Kubernetes实战指南(三十三):都0202了,你还在手写k8s的yaml文件?

    目录 1. k8s的yaml文件到底有多复杂 2. 基于图形化的方式自动生成yaml 2.1 k8s图形化管理工具Ratel安装 2.2 使用Ratel创建生成yaml文件 2.2.1 基本配置 2. ...