源码下载: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. VSFTP问题解决

    支持 root 登录 在 /etc/vsftpd/{ftpusers,user_list} 中注释掉 root 添加 allow_writeable_chroot=YES, 允许在只读文件登录, 否则 ...

  2. CUDA线程、线程块、线程束、流多处理器、流处理器、网格概念的深入理解

    一.与CUDA相关的几个概念:thread,block,grid,warp,sp,sm. sp: 最基本的处理单元,streaming processor  最后具体的指令和任务都是在sp上处理的.G ...

  3. 2020-04-08:为什么TCP握手需要三次?

    假想一下,如果我们去掉了第三次呢?如果只是第二次建立的话,服务端和客户端就已经建立,但是如果客户端没有收到服务端的回应?这个时候,客户端认为没有建立,服务端却为认为建立成功,并保存了必要的资源,如果出 ...

  4. C#LeetCode刷题之#884-两句话中的不常见单词(Uncommon Words from Two Sentences)

    问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3816 访问. 给定两个句子 A 和 B . (句子是一串由空格分 ...

  5. 面试官:怎么做JDK8的垃圾收集器的调优?

    面试官:怎么做JDK8的垃圾收集器的调优? 看着面试官真诚的眼神,心中暗想看起来年纪轻轻却提出如此直击灵魂的问题.擦了擦额头上汗,我稍微调整了一下紧张的情绪,对面试官说: 在JDK8中有Serial收 ...

  6. golang的树结构三种遍历方式

    package main import "log" type node struct { Item string Left *node Right *node } type bst ...

  7. Linux下安装Readis

    Redis的官方下载网址是:http://redis.io/download  (这里下载的是Linux版的Redis源码包) Redis服务器端的默认端口是6379. 首先我们先把整体的流程先书写下 ...

  8. webpack打包原理

    什么是 webpack ? 本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler).当 webpack 处理应用程序时,它会递归地构建一个依 ...

  9. Istio Routing 实践掌握virtualservice/gateway/destinationrule/AB版本发布/金丝雀发布

    原文 在学习像 Istio 这样的新技术时,看一下示例应用程序总是一个好主意. Istio repo 有一些示例应用程序,但它们似乎有各种不足. 文档中的 BookInfo 是一个很好的示例. 但是, ...

  10. Url跳转漏洞常见

    Url跳转漏洞常见出现点: 1.用户登录.统一身份认证处,认证完后会跳转. 2.用户分享.收藏内容过后,会跳转. 3.跨站点认证.授权后,会跳转. 4.站内点击其它网址链接时,会跳转. Url跳转漏洞 ...