basicInterpreter1.01 支持分支语句
源码:https://files.cnblogs.com/files/heyang78/basicInterpreter-20200531-1.rar
输入:
count=
print(count)
if count== then print("count等于10")
if count< then print("count小于20")
if count> then print("count大于5")
print("程序结束")
输出:
原文=count= print(count) if count== then print("count等于10") if count< then print("count小于20") if count> then print("count大于5") print("程序结束")
Index Type No Text Type Desc
------------------------------------------------------------------------------------
count Variable
= =
Number
print Function
( (
count Variable
) )
if if
count Variable
== ==
Number
then then
print Function
( (
"count等于10" String
) )
if if
count Variable
< then
Number
then then
print Function
( (
"count小于20" String
) )
if if
count Variable
> >
Number
then then
print Function
( (
"count大于5" String
) )
print Function
( (
"程序结束" String
) )
执行结果:
"count等于10"
"count小于20"
"count大于5"
"程序结束"
核心代码:
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_ASSIGN=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
public static final int TYPE_EQUAL=8; // ==
public static final int TYPE_IF=9; // if
public static final int TYPE_THEN=10; // then
public static final int TYPE_LESSTHAN=10; // <
public static final int TYPE_BIGGERTHAN=11; // >
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_ASSIGN) {
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";
}else if(type==TYPE_EQUAL) {
return "==";
}else if(type==TYPE_IF) {
return "if";
}else if(type==TYPE_THEN) {
return "then";
}else if(type==TYPE_LESSTHAN) {
return "<";
}else if(type==TYPE_BIGGERTHAN) {
return ">";
}
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 text) {
tokens = new ArrayList<Token>(); String swallowed = "";
for (int i = 0; i < text.length(); i++) {
char c = text.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_BIGGERTHAN));
}else if (c == '<') {
addTextToList(swallowed);
swallowed=""; tokens.add(new Token(c, Token.TYPE_LESSTHAN));
} else if (c == '=') {
int next=i+1;
if(next<text.length() && text.charAt(next)=='=') {
// ==
addTextToList(swallowed);
swallowed="";
tokens.add(new Token("==",Token.TYPE_EQUAL));
i++;
}else {
// =
addTextToList(swallowed);
swallowed="";
tokens.add(new Token(c, Token.TYPE_ASSIGN));
}
} else if(c == '\"') {
addTextToList(swallowed);
swallowed=""; int idx=i+1; while(idx<text.length()) {
char cEnd = text.charAt(idx); if (cEnd == '\"') {
break;
} idx++;
} String sub=text.substring(i, idx+1);
tokens.add(new Token(sub, Token.TYPE_STRING));
i=idx;
} else {
swallowed += c;
}
} setTokenIndexes();
} private void addTextToList(String text) {
if("if".equalsIgnoreCase(text)) {
tokens.add(new Token(text, Token.TYPE_IF));
}else if("then".equalsIgnoreCase(text)) {
tokens.add(new Token(text, Token.TYPE_THEN));
}else 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_ASSIGN) {
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.");
}
}
}
}else if(token.getType()==Token.TYPE_IF) {
int vLeft,vRight;
String oprand; // get left value
token=fetchToken();
if(token.getType()==Token.TYPE_VARIABLE) {
String varibleName=token.getText(); if(varmap.containsKey(varibleName)) {
vLeft=varmap.get(varibleName);
}else {
throw new Exception("Variable:'"+varibleName+"' was not assigned.");
}
}else if(token.getType()==Token.TYPE_NUMBER) {
vLeft=Integer.parseInt(token.getText());
}else {
throw new Exception("Expected:number/variable actual:"+token.getText()+" "+token);
} // get ==,<,>
token=fetchToken();
if(token.getType()!=Token.TYPE_EQUAL && token.getType()!=Token.TYPE_LESSTHAN && token.getType()!=Token.TYPE_BIGGERTHAN) {
throw new Exception("Expected:'== or > or <' actual:"+token.getText()+" "+token);
}
oprand=token.getText(); // get right
token=fetchToken();
if(token.getType()==Token.TYPE_VARIABLE) {
String varibleName=token.getText(); if(varmap.containsKey(varibleName)) {
vRight=varmap.get(varibleName);
}else {
throw new Exception("Variable:'"+varibleName+"' was not assigned.");
}
}else if(token.getType()==Token.TYPE_NUMBER) {
vRight=Integer.parseInt(token.getText());
}else {
throw new Exception("Expected:number/variable actual:"+token.getText()+" "+token);
} // Compare
if(compare(vLeft,oprand,vRight)) {
// get then
token=fetchToken();
if(token.getType()!=Token.TYPE_THEN) {
throw new Exception("Expected:'then' actual:"+token.getText()+" "+token);
}
}else {
// 跳过两个token(then及后面的dosth)
fetchToken();
fetchToken();
}
}
}
} private boolean compare(int vLeft,String oprand,int vRight) throws Exception{
if("==".equals(oprand)) {
return vLeft==vRight;
}else if(">".equals(oprand)) {
return vLeft>vRight;
}else if("<".equals(oprand)) {
return vLeft<vRight;
}else {
throw new Exception("oprand should be == or > or < but not.");
}
} 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--;
}
}
}
--2020年5月31日--
basicInterpreter1.01 支持分支语句的更多相关文章
- Linux Shell系列教程之(十三)Shell分支语句case … esac教程
本文是Linux Shell系列教程的第(十三)篇,更多Linux Shell教程请看:Linux Shell系列教程 分支语句非常实用,基本上高级语言都支持分支语句(python 没有),大多数都使 ...
- 【Python 09】汇率兑换2.0-2(分支语句)
分支语句:根据判断条件选择程序执行路径 1.使用方法 if <条件1>: <语句块1> elif <条件2>: <语句块2> ... else: < ...
- JavaScript基础4——关于语句流程控制(分支语句、循环语句等)
分支语句 (1)if...else...语句,基本格式分三种,如下 <script type="text/javascript"> var i=50; //if语句 i ...
- Shell脚本应用(for、while循环语句和case分支语句)
1.for:读取不同的变量值,逐个执行同一组命令,直到取值完毕退出,变量值以空格分隔 语法: for 变量值 in 取值列表 do 命令序列 done 2.while:重复测试某个条件,成立则执 ...
- Python 为什么不支持 switch 语句?
本文出自"Python为什么"系列,请查看全部文章 在这篇文章里,我们会聊一聊为什么 Python 决定不支持 switch 语句. 为什么想要聊这个话题呢? 主要是因为 swit ...
- 【java开发】分支语句、循环语句学习
一.Java分支语句类型 if-else 语句 switch 关于if-esle语句可以拆分为三种 if语句 if(条件){语句块;} if-else语句if(条件语句){语句块;} if-else ...
- 运算符 与 分支语句:if ,else if,else;switch case
分支语句: if else if else : switch case --如何使用 if else if else: Console. ...
- JavaScript语法、对话框。分支语句
一.用法 其所在的位置有三块,1.head里面 2.body里面 3.</html>后 一般都写在</html>后 其用法为<script></scr ...
- HTML基础--JS简介、基本语法、类型转换、变量、运算符、分支语句、循环语句、数组、函数、函数调用.avi
JS简介 1.JavaScript是个什么东西? 它是个脚本语言,需要有宿主文件,它的宿主文件是HTML文件. 2.它与Java什么关系? 没有什么直接的联系,Java是Sun公司(已被Oracle收 ...
随机推荐
- Nginx介绍,安装,配置
引言 为什么要学习Nginx 问题一: 客户端到底要将请求发送给哪台服务器? 问题二: 如果所有客户端的请求都发送给了服务器1,那另一台岂不是废了 问题三: 客户端发送的请求可能是申请动态资源的,也可 ...
- 微信小程序开发着工具获取和更新newticket
newticket是微信开发者工具和微信后台交互的凭证.大多数工具的操作都是需要newticket. 如何获取newticket? 打开开发者工具,依次点击菜单设置->通用设置->代理,使 ...
- 数据结构C++实现邻接矩阵存储图
定义邻接矩阵存储的图类.[实验要求] 1. 创建一个邻接矩阵存储的图: 2. 返回图中指定边的权值: 3. 查找图中某顶点的第一个邻接顶点.某顶点关于另一个顶点的下一个邻接顶点序号: 4. 图的深度优 ...
- 微博AnalysisQl动态数据视图元数据设计
前言 目前,AnalysisQl 数据视图的元数据(维度.指标.指标计算器)需要通过代码(API)或资源文件的形式硬编码,应用启动时,按照声明的顺序依次注册.这种模式下,数据视图是 静态 的,任何一项 ...
- Ubuntu 18.04 安装、配置和美化
本文章修改自inkss的博文 为什么要修改原文? 本来我是想自己写这么一篇的,但是没想到在百度一搜,居然一篇好文.我之前没看到,真是可惜. 这篇文章主要是帮助我记录一些东西,如题. 原文虽然不错,但是 ...
- Spring Boot系列(三):Spring Boot整合Mybatis源码解析
一.Mybatis回顾 1.MyBatis介绍 Mybatis是一个半ORM框架,它使用简单的 XML 或注解用于配置和原始映射,将接口和Java的POJOs(普通的Java 对象)映射成数据库中的记 ...
- 修改linux 动态ip为静态ip
vi /etc/sysconfig/network-scripts/ifcfg-ens33 BOOTPROTO=static 设置网卡引导协议为 静态 ONBOOT=yes 网卡开机自启动 配置[IP ...
- 在vue中使用echarts报错Cannot read property getAttribute of null
报错信息如下: 报错代码: mounted() { // ... this.drwaCharts() // drawCharts方法为自己定义的包含渲染 echarts 图表的方法 // ...} 之 ...
- SSM框架环境搭建
SSM基础环境搭建 创建maven工程 next,finish,等待创建完成,创建完成后,src/main下只有webapp文件夹,我们需要手动创建java和resources,鼠标右击main,ne ...
- magento2 pub/static没有adminhtml,frontend的解决方案
(1) 运行php bin/magento setup:static-content:deploy (2) 检查pub/static有没有.htaccess文件 (3) php bin/magento ...