basicInterpreter1.02 增加对for循环的支持
源码下载:https://files.cnblogs.com/files/heyang78/basicInterpreter102-20200531-2.rar
输入:
- for x= to
- print(x)
- next
- print("")
- for y= to
- print(y)
- next
- print("程序结束")
输出:
- 原文= for x= to print(x) next print("") for y= to print(y) next print("程序结束")
- Index Type No Text Type Desc
- ------------------------------------------------------------------------------------
- for for
- x Variable
- = =
- Number
- to to
- Number
- print Function
- ( (
- x Variable
- ) )
- next next
- print Function
- ( (
- "" String
- ) )
- for for
- y Variable
- = =
- Number
- to to
- Number
- print Function
- ( (
- y Variable
- ) )
- next next
- print Function
- ( (
- "程序结束" String
- ) )
- 执行结果:
- ""
- "程序结束"
以下是核心类:
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; // >
- public static final int TYPE_FOR=12; // For
- public static final int TYPE_TO=13; // To
- public static final int TYPE_NEXT=14; // Next
- 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 ">";
- }else if(type==TYPE_FOR) {
- return "for";
- }else if(type==TYPE_TO) {
- return "to";
- }else if(type==TYPE_NEXT) {
- return "next";
- }
- 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("for".equalsIgnoreCase(text)) {
- tokens.add(new Token(text, Token.TYPE_FOR));
- }else if("to".equalsIgnoreCase(text)) {
- tokens.add(new Token(text, Token.TYPE_TO));
- }else if("next".equalsIgnoreCase(text)) {
- tokens.add(new Token(text, Token.TYPE_NEXT));
- }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;
- import java.util.Stack;
- class LoopInfo{
- public LoopInfo(String loopValueName,int limit,int startLocation) {
- this.loopValueName=loopValueName;
- this.limit=limit;
- this.startLocation=startLocation;
- }
- String loopValueName;
- int limit;
- int startLocation;
- }
- public class Interpreter {
- private List<Token> tokens;
- private int tokenIdx;
- private Map<String,Integer> varmap;
- private Stack<LoopInfo> loopStack;
- public Interpreter(List<Token> tokens) throws Exception{
- this.tokens=tokens;
- this.tokenIdx=0;
- varmap=new HashMap<String,Integer>();
- loopStack=new Stack<LoopInfo>();
- execute();
- }
- private void execute() throws Exception{
- 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();
- }
- }
- else if(token.getType()==Token.TYPE_FOR) {
- token=fetchToken();
- if(token.getType()!=Token.TYPE_VARIABLE) {
- throw new Exception("Expected:variable actual:"+token.getText()+" "+token);
- }
- 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);
- }
- token=fetchToken();
- if(token.getType()!=Token.TYPE_TO) {
- throw new Exception("Expected:to actual:"+token.getText()+" "+token);
- }
- token=fetchToken();
- if(token.getType()!=Token.TYPE_NUMBER) {
- throw new Exception("Expected:number actual:"+token.getText()+" "+token);
- }
- int limit=Integer.parseInt(token.getText());
- int variableValue=varmap.get(varibleName);
- if(variableValue<=limit) {
- loopStack.push(new LoopInfo(varibleName,limit,tokenIdx));
- }else {
- fetchToken();
- }
- }
- else if(token.getType()==Token.TYPE_NEXT) {
- doNext();
- }
- }
- }
- private void doNext() {
- LoopInfo info=loopStack.pop();
- int variableValue=varmap.get(info.loopValueName)+1;
- varmap.put(info.loopValueName, variableValue);
- if(variableValue>info.limit) {
- //
- }else {
- loopStack.push(info);
- tokenIdx=info.startLocation;
- }
- }
- 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--;
- }
- }
- }
入口类:
- 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\\05.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();
- }
- }
- }
--2020年5月31日--
basicInterpreter1.02 增加对for循环的支持的更多相关文章
- MWeb 1.3.7 发布!增加发布到 Wordpress 等支持 MetaWeblog API 的服务,如:Wordpress 博客、新浪博客、cnblogs、oschina。
MWeb 1.3.7 版的新功能 增加发布到 Wordpress 等支持 Metaweblog API 的服务,目前经测试过的有: Wordpress 博客.新浪博客.cnblogs.oschina. ...
- AndroidInject项目使用动态代理增加对网络请求的支持
以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/3540427.html AndroidInject项目是我写的一 ...
- 在内核中增加对yaffs文件系统的支持
自己最近在搞一些内核以及根文件系统的移植,就涉及到了需要在内核中增加对yaffs文件系统的支持.在网上找了一些文档后,自己将具体的操作过程做了一个总结,方便以后查询使用: 1.获取yaffs源码 YA ...
- NGINX 加载动态模块(NGINX 1.9.11开始增加加载动态模块支持)
NGINX 1.9.11开始增加加载动态模块支持,从此不再需要替换nginx文件即可增加第三方扩展.目前官方只有几个模块支持动态加载,第三方模块需要升级支持才可编译成模块. tinywan@tinyw ...
- dubbo/dubbox 增加原生thrift及avro支持
(facebook) thrift / (hadoop) avro / (google) probuf(grpc)是近几年来比较抢眼的高效序列化/rpc框架,dubbo框架虽然有thrift的支持,但 ...
- cocos2d-x编译到android平台后,增加返回键和菜单键支持
在头文件中增加函数 virtual void keyBackClicked();//android返回键 virtual void keyMenuClicked();//android菜单键 在ini ...
- subilme增加对markdown的高亮支持
sublime2对markdown原生主题支持都没有, 需要通过插件补充 1.插件安装 通过Package Control安装下列插件: Markdown Extended Monokai Exten ...
- Touch Punch在移动设备上面增加jQuery UI的触摸支持|Jquery UI 支持移动端 触摸滑动等
jQuery UI是我们前台开发常用的UI前端类库,但是目前的jQuery UI用户界面类库在互动和widget上并不支持touch事件.这意味着你在桌面上设计的优雅的UI可能在触摸设备,例如,ipa ...
- 增加响应header让ajax支持跨域
ajax请求数据步骤 发送请求--->浏览器接受响应--->判断是否是同域下 是的话,就把响应数据返回给ajax.不是的话就提醒禁止跨域请求. 现在可以在响应头重增加 header(&qu ...
随机推荐
- DotNet Core
安装 dotnet add package Pomelo.EntityFrameworkCore.MySql 使用 MySQL 作为后端 在继承 DbContext 类中重写 OnConfig ...
- 【Spring Security】1.快速入门
1 导入Spring Security的相关依赖 <dependency> <groupId>org.springframework.boot</groupId> ...
- C#LeetCode刷题之#88-合并两个有序数组(Merge Sorted Array)
问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3686 访问. 给定两个有序整数数组 nums1 和 nums2, ...
- Homekit_温湿度传感器
本款产品为Homekit相关产品需要使用苹果手机进行操作,有兴趣的可以去以下链接购买: https://item.taobao.com/item.htm?spm=a1z10.1-c.w4004-112 ...
- oracle正则表达式语法介绍及实现手机号码匹配方法
Oracle10g提供了在查询中使用正则表达的功能,它是通过各种支持正则表达式的函数在where子句中实现的.本文将简单的介绍oracle正则表达式常用语法,并通过一个手机特号匹配的例子演示正则表达式 ...
- 一文看懂 Netty 架构设计
本文重点分析 Netty 的逻辑架构及关键的架构质量属性,希望有助于大家从 Netty 的架构设计中汲取营养,设计出高性能.高可靠性和可扩展的程序. Netty 的三层架构设计 Netty 采用了典型 ...
- day1 计算机的组成
1.计算机,是用于高速计算的电子机器,具有数值计算, 逻辑判断,储存记忆的功能. 2.计算机由硬件系统和软件系统组成构成. 3.计算机中所有的运行程序都是在内存中进行的,暂时存放在CPU中的运算数据 ...
- PYTHON-错误-函数有返回值未接收导致替换不成功
#1.有返回值,没有赋值,替换不成功 cxj = 'guapi' cxj.replace(cxj,'2b') print(cxj) #2.有返回值,赋值,替换成功 cxj = 'guapi' cxj ...
- 真正从底层理解 Synchronized 实现原理
实现synchronized的基础有两个:Java 对象头和 Monitor. 在虚拟机规范中定义了对象在内存中的布局,主要由以下 3 部分组成: 对象头 实例数据 对齐填充 而synchronize ...
- unsigned char printf 如何输出
参考链接:https://blog.csdn.net/m0_37362454/article/details/88639668 #include <stdio.h> int main() ...