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收 ...
随机推荐
- 微信小程序 progress 进度条 内部圆角及内部条渐变色
微信小程序progress进度条内部圆角及渐变色 <view class="progress-box"> <progress percent="80&q ...
- 2020-07-24:聊一下zookeeper的同步算法。
福哥答案2020-07-24: 同步算法基于 ZAB 协议,一种快速 Paxos 算法. 快速Paxos算法Paxos算法可能出现死循环,就是在两个Proposer总是在交替prepare.并且,Pa ...
- Flutter 容器 (1) - Center
Center容器用来居中widget import 'package:flutter/material.dart'; class AuthList extends StatelessWidget { ...
- 解决pgAdmin4启动失败方法
1. 问题现象 有时pgadmin 4启动仅显示启动界面, 或者 点击图标一直都没反应,启动界面用鼠标点击下就消失了, 然后过很长时间就保错: the application server could ...
- 《Java从入门到失业》第二章:Java环境(一):Java SE安装
从这一章开始,终于我们可以开始正式进入Java世界了.前面我们提到过,Java分三个版本,我们这里只讨论Java SE. 2.1Java SE安装 所谓工欲善其事,必先利其器.第一步,我们当然是要下载 ...
- JAVA 读取excel文件成List<Entity>
package com.fsinfo.common.utils; import com.fsinfo.modules.enterprise.entity.EnterpriseRecordEntity; ...
- JAVA字符串的替换replace、replaceAll、replaceFirst的区别解析。
String str = "i.like.cat"; System.out.println(str.replace(".", "!")); ...
- machine vision plan
以OpenCV+C#/C++为主,Halcon+C#/C++.LabVIEW+NI Vision,其他还不了解 目前:Halcon+C# 1.完成:测量定位,表面质量检测 2.完成1后开始:OpenC ...
- python 多个装饰器的调用顺序分析
一般情况下,在函数中可以使用一个装饰器,但是有时也会有两个或两个以上的装饰器.多个装饰器装饰的顺序是从里到外(就近原则),而调用的顺序是从外到里(就远原则) 样例: def func1(func): ...
- JavaScript的数据类型判断学习理解和数据处理
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...