Giter Site home page Giter Site logo

xawi2000 / jminilang Goto Github PK

View Code? Open in Web Editor NEW

This project forked from bajdcc/jminilang

0.0 1.0 0.0 7.62 MB

用Kotlin实现的编译器和虚拟机,并在此基础上构建操作系统。

Home Page: http://files.cnblogs.com/files/bajdcc/jMiniLang-manual.pdf

License: MIT License

CSS 3.12% JavaScript 0.22% HTML 3.50% Kotlin 93.16%

jminilang's Introduction

jMiniLang - GLR Compiler and Virtual Machine (Kotlin)

Build status

设计思路:https://zhuanlan.zhihu.com/p/28540783

视频演示:https://www.bilibili.com/video/av13294962/

语法参考(LR状态转移表)

一言以蔽之,本项目涉及的**包括:

  • 编译原理(涵盖正则文法(com.bajdcc.util.lexer)、LR1文法(com.bajdcc.LALR1)、LL1文法(com.bajdcc.LL1)),重点:语法制导翻译、自定义语义动作,包含自动机的生成(非确定性有限自动机-NFA、确定性有限自动机-DFA、非确定性下推自动机-NPDA、确定性下推自动机-PDA)、LR或LL表的生成(com.bajdcc.LALR1/LL1.syntax)、语法分析(com.bajdcc.LALR1.grammar)、语义分析(com.bajdcc.LALR1.semantic)、语法树的生成(com.bajdcc.LALR1.grammar.tree)、中间代码的生成(com.bajdcc.LALR1.grammar.codegen),其中LR分析部分要感谢vczh大牛提供的C++源码
  • 虚拟机(com.bajdcc.LALR1.interpret),包含基于栈的虚拟机指令的设计(com.bajdcc.LALR1.grammar.runtime)(没有指针,只有引用)、外部方法导入、二进制码生成、隐性类型转换、实现N元运算
  • 语法特性(com.bajdcc.LALR1.grammar.Grammar),包含foreach/yield的实现、Lambda的实现、管道的实现、import导入代码页的实现、实现try/catch,及一些语法糖
  • 操作系统,包含多进程的实现(RuntimeProcess)、微服务架构(ModuleTask)、基于管道的进程同步机制的实现(ModuleProc)、用户进程的实现(ModuleUserBase意思是可以挂掉而不影响系统)
  • Web网页服务器的实现(com.bajdcc.web),包含REST接口的实现、REST服务与jMiniLang用户进程的消息传递机制、Spring-boot的使用
  • UI(com.bajdcc.LALR1.ui),包含部分SVG指令的绘制、操作系统层面的UI服务设计、控制台的实现、Ctrl-C指令的实现、对话框Dialog的实现、支持中文宽字符的显示、支持RGB24位彩色字符的显示、支持背景颜色的设置
  • 基于jMiniLang语言实现的面向对象特性(ModuleClass参照JS的原型链)
  • 函数式编程接口的实现(ModuleFunction
  • LISP的jMiniLang实现(ModuleLisp),B站视频链接
  • 语言集成查询(LINQ)的jMiniLang实现(ModuleStdBase,参考Vlpp),类似Java 8 Stream链式/流式操作

一言以蔽之,本项目涉及的玩法包括:

  • Spring-boot与layui制作的管理后台,包括资源查看、文档查看、在线编译
  • UserService RING3级用户服务,实现FORK管道互斥
  • 开发中 【C语言解释器】类似CParser的类设计,参考GO语言库,代码
  • Shell层面的管道机制,类似echo a | > b.txt等,语法层面有Bash接口的实现
  • 基于Map数据的原型链实现面向对象特性(ModuleClass),应用有:状态机实例--百度新闻(URNews)、行为树实例-AI(URAI)、状态机实例-歌词动画(URMusic)、图论-路由距离算法-PC(URPC)
  • BadApple黑白动画播放(test badapple),测试IO性能
  • SSH机制(ModuleNet),采用netty实现远程命令
  • Spring-boot制作而成的网页服务器(localhost:8080),与我们的jMiniLang语言进行交互,可以查看jMiniLang虚拟机的各项指标
  • 哲学家进餐问题(test philotest philo2
  • LISP的实现(test lisp
  • LINQ的实现(test linq
  • 一个自制的基于NIO的简易HTTP服务器(test web
  • 还有一些其他的好玩的但不想费力介绍的冷门内容,上面的部分内容我懒得截图了

jMiniLang is a simplified compiler/vm framework. Developed by bajdcc. PS. LR Analysis refers to VFS developed by vczh.

本项目是一个LR编译器、虚拟机一体化工程,并且对虚拟机进行了拓展,参考了操作系统设计的**。

Features(特性)

  1. 词法分析阶段。Lexer which generates NFA and DFA.
  2. 语法分析、词法分析、制导翻译。Parser which implements LALR(1) Grammar with optional semantic action.
  3. 语义分析。Customized semantic analysis.
  4. 可打印语法树。Printable syntax tree.
  5. 基于栈的自定义指令集。Stack-based instruction design.
  6. Kotlin本地方法导入。Native method.
  7. 代码页导入/导出。Import and export of code page.
  8. 代码页序列化。Serializable code page.
  9. 匿名函数及闭包。Lambda functions and Closure.
  10. 语法/词法错误提示。Display grammar and semantic errors.
  11. 管道机制。Pipe.
  12. 多进程机制。Multiple process.
  13. 同步/异步执行代码。Load file with Sync/Async.
  14. 虚拟机。Virtual machine.
  15. 支持彩色界面。Support Colorful GUI.
  16. 函数式编程。Functional programming.
  17. LISP.
  18. 网络流。Socket stream.
  19. 虚拟文件系统。Save/Load file or VFS.
  20. 基于原型的类设计。Class prototype.
  21. Bash Interface.
  22. 数组/词典初始化。Array/Map initialize list.
  23. 异常机制。Try/Catch/Throw.
  24. 行为树。Behavior Tree, including PC network simulator.
  25. 用户级进程。RING 3 Process, including User Service, fork.
  26. 网页服务器。Web Server, including Online Compiler and Runner.
  27. C语言解析。CParser class on ModuleUser.

What it generates(产生)

  • 正则表达式、状态机。Structures of Regex, NFA and DFA Table.
  • 分析表。Structures of LL/LR Table.
  • 语义分析指令。Structures of semantic instructions.
  • 语法树。Structures of syntax tree.
  • 代码页。Structures of code page.
  • 虚拟机指令。Virtual machine instructions.
  • 运行时环境。Runtime environment.

Virtual Machine OS

An OS running on jMiniLang compiler and interpreter.

Now has commands:(现在主窗口支持的cmd命令)

Tasks:(使用方法如:@system halt

  • System
  • Utility
  • Remote
  • UI
  • Store
  • Proc

UI:(使用方法如:@ui on clock

  • Clock
  • Hitokoto
  • Monitor

Toggle UI:

  • task ui on/off clock
  • task ui on/off hitokoto
  • task ui on/off monitor

Implemented IPC, usage:(微服务)

  • task system now -> Get system time
  • task util calc 1+2*3 -> Val = 7
  • task ui print hello world -> Remote window
  • task ui path M 100 100 L 200 200 -> SVG

Utility:

  • task util doc g_func_fold -> Document
  • task util reverse ...
  • task util toupper ...
  • task util sum ...
  • task util product ...
  • task util palindrome ...

Tests:(测试命令,直接在主窗口cmd输入,Ctrl-C中止)

  • test philo/philo2: Multi-processing and synchronization
  • test lisp: LISP language
  • test font: Support Chinese Language(wide font)
  • test fork: Test fork
  • test class: Test AOP and Prototype for class
  • test bash: Test bash interface
  • test try: Test try/catch
  • test badapple: Test ascii output, code in BadApple
  • test dialog: Test JOptionPane.showXXXDialog
  • test linq: Test LINQ
  • test proc: Test Ring 3 API
  • test proc2: Test Ring 3 code with input
  • test web: HTTP Web Server

Implemented MSG, usage:(远程控制)

  • Create server: msg server PORT | filter pipe
  • Create client: other pipe | msg connect IP:PORT

PC command:

  • pc add A 10 10 100 100
  • pc remove A
  • pc msg A B

LINQ:

  • from(list) or from(array)
  • range(begin, end)
  • Function: select, where, first, last, max, sum, for_each, group_by, distinct, union, etc.

TASK PROC:

  • exec:执行代码
  • exec_file:读文件执行代码
  • kill:中止用户进程
  • info:取得用户进程状态(用于浏览器远程回调)

USER HANDLE:(用户级进程支持的句柄种类)

  • pipe:管道,类似Go中的chan,用于跨进程同步,读阻塞,写不阻塞。
  • share:共享,同步跨进程数据共享。
  • file:文件,虚拟文件接口,同步操作。
  • window:窗口,创建JFrame窗口,异步,包括绘制、消息。
  • net:网络,包括HTTP请求,OkHttp实现,异步。

Dependencies:(使用的开源库,下面为部分)

  • JSON格式化:fastjson
  • 实现远程命令SSH:netty
  • 后端及API:spring-boot
  • 网页模版:thymeleaf
  • 前端交互:vue
  • 前端样式:layui
  • Markdown文档转换:flexmark
  • 数据结构:guava
  • HTTP请求:okhttp
  • JAR打包:shadow

Manual

Simplified Chinese Version

Example

Web Server

  1. Spring Boot API, port 8080
  2. Java NIO, port 8088
  3. Render Markdown using FlexMark

Front-end: LayUI(前端)

1. Spring Boot API

Front-end: LayUI + Vue.js

API: Json + RestController

Back-end: jMiniLang API Handler (RING 3 Process)

Run on Server

** Online Compiler Example V: GUI User Window **

Screenshot GUI-1

window.txt

import "user.base";
var w = g_window("test window");
var width = 800;
var height = 600;
var border = 10;
w."msg"(0, width, height); // CREATE
w."svg"('M', border, border);
w."svg"('L', width - border, border);
w."svg"('L', width - border, height - border);
w."svg"('L', border, height - border);
w."svg"('L', border, border);
w."svg"('M', border * 2, border * 2);
w."svg"('S', width - border * 4, height - border * 4);
w."str"(1, g_string_rep("Hello world! ", 20));
w."svg"('m', 0, 200);
w."str"(1, g_string_rep("Hello world! ", 20));
w."svg"('m', 0, 200);
w."str"(0, g_string_rep("Hello world! ", 20));
g_sleep_s(1);
w."msg"(2, 0, 0); // WAIT FOR CLOSE

** Online Compiler Example IV: Mutex **

import "user.base";

var channel = g_pipe("TEST-MUTEX");
var goods = g_share("TEST-MUTEX#GOOD", g_from([]));
var index = g_share("TEST-MUTEX#INDEX", 0);
g_create_dir("/example-mutex");

var new_id = func ~() -> index."set!"(lambda(a) -> a++);
var enqueue = func ~(id) -> goods."get!"(lambda(a) -> a."push"(id));
var dequeue = func ~() -> goods."get!"(lambda(a) -> a."pop"());

var consumer_id = func ~(id) -> "/example-mutex/consumer-" + id;
var producer_id = func ~(id) -> "/example-mutex/producer-" + id;

var consumer = func ~(id) {
    var obj;
    var now = g_get_timestamp();
    channel."writeln"("消费者 #" + id + " 已启动");
    foreach (var i : g_range(1, 5)) {
        while (g_is_null(obj := dequeue())) {}
        channel."writeln"("消费者 #" + id + " 收到:" + obj);
    }
    channel."writeln"("消费者 #" + id + " 已退出");
    var span = g_get_timestamp() - now;
    g_write_file(consumer_id(id), "消费者 #" + id + " 用时 " + span + "ms", true, true);
};

var producer = func ~(id) {
    var obj;
    var now = g_get_timestamp();
    channel."writeln"("生产者 #" + id + " 已启动");
    foreach (var i : g_range(1, 5)) {
        enqueue(obj := new_id());
        channel."writeln"("生产者 #" + id + " 发送:" + obj);
    }
    channel."writeln"("生产者 #" + id + " 已退出");
    var span = g_get_timestamp() - now;
    g_write_file(producer_id(id), "生产者 #" + id + " 用时 " + span + "ms", true, true);
};

var child = false;

foreach (var i : g_range(1, 5)) {
    if (g_fork() == -1) {
        consumer(i);
        child := true;
        break;
    }
    if (g_fork() == -1) {
        producer(i);
        child := true;
        break;
    }
}

if (child) { return; }

if (g_fork() == -1) {
    var i = 0;
    while (i < 10) {
        foreach (var id : g_range(1, 5)) {
            if (g_query_file(consumer_id(id)) == 1) {
                i++;
                channel."writeln"(g_read_file(consumer_id(id)));
                g_delete_file(consumer_id(id));
            }
            if (g_query_file(producer_id(id)) == 1) {
                i++;
                channel."writeln"(g_read_file(producer_id(id)));
                g_delete_file(producer_id(id));
            }
        }
    }
    channel."write"(g_noop_true);
    g_delete_file("/example-mutex");
    return;
}

channel."pipe"(g_system_output());

Output:

运行成功!PID:24
消费者 #1 已启动
生产者 #1 已启动
消费者 #2 已启动
生产者 #2 已启动
消费者 #3 已启动
生产者 #3 已启动
消费者 #4 已启动
生产者 #4 已启动
消费者 #5 已启动
生产者 #5 已启动
生产者 #1 发送:1
消费者 #2 收到:1
生产者 #2 发送:2
消费者 #3 收到:2
生产者 #3 发送:3
...
消费者 #3 已退出
生产者 #4 发送:19
消费者 #4 收到:19
消费者 #4 已退出
生产者 #5 发送:20
消费者 #5 收到:20
消费者 #5 已退出
生产者 #1 发送:21
生产者 #1 已退出
消费者 #1 收到:21
消费者 #1 已退出
生产者 #2 发送:22
生产者 #2 已退出
生产者 #3 发送:23
生产者 #3 已退出
生产者 #4 发送:24
生产者 #4 已退出
生产者 #5 发送:25
生产者 #5 已退出
消费者 #2 收到:22
消费者 #2 收到:23
消费者 #2 收到:24
消费者 #2 收到:25
消费者 #2 已退出
生产者 #1 用时 106ms
消费者 #2 用时 131ms
生产者 #2 用时 107ms
消费者 #3 用时 91ms
生产者 #3 用时 104ms
消费者 #4 用时 88ms
生产者 #4 用时 101ms
消费者 #5 用时 89ms
生产者 #5 用时 100ms
消费者 #1 用时 108ms

正常退出

** Online Compiler Example III: Fork **

Fork support yield

import "user.base";

var channel = g_pipe("TEST-FORK");

var pid = g_null;
if ((pid := g_fork()) != -1) { // 父进程读取管道
    g_puts("父进程 PID:" + g_pid());
    g_puts("父进程 FORK 返回:" + pid);
    g_puts(channel, "读取管道:");
    channel."pipe"(g_system_output());
} else { // 子进程写入管道
    channel."writeln"("子进程 FORK 返回:" + pid);
    var range = yield ~() { // 枚举器
        for (var i = 0; i < 3; i++) {
            yield g_fork(); // 枚举返回值
        }
    };
    foreach (var i : range()) {
        var txt = "这是一条测试消息! PID:" + g_pid() + " 编号:" + i;
        channel."writeln"(txt);//写管道
        g_sleep_s(1);
    }
    channel."write"(g_noop_true);//发送管道关闭信号
}

Output:

运行成功!PID:24
父进程 PID:24
父进程 FORK 返回:25
class= system::pipe 字符串(system::pipe)
读取管道:
子进程 FORK 返回:-1
这是一条测试消息! PID:25 编号:26
这是一条测试消息! PID:26 编号:-1
这是一条测试消息! PID:32 编号:-1
这是一条测试消息! PID:33 编号:-1
这是一条测试消息! PID:25 编号:32
这是一条测试消息! PID:26 编号:33
这是一条测试消息! PID:32 编号:38
这是一条测试消息! PID:33 编号:39
这是一条测试消息! PID:38 编号:-1
这是一条测试消息! PID:39 编号:-1
这是一条测试消息! PID:40 编号:-1
这是一条测试消息! PID:41 编号:-1
这是一条测试消息! PID:25 编号:40
这是一条测试消息! PID:26 编号:41

正常退出

** Online Compiler Example II: Pipe **

Reader

import "user.base";

var channel = g_pipe("TEST");
g_puts(channel, "读取管道:");
channel."pipe"(g_system_output());//将管道重定向至输出流

Writer

import "user.base";

var channel = g_pipe("TEST");
g_puts(channel, "写入管道:");
for (var i = 0; i < 10; i++) {
    var txt = "这是一条测试消息! 编号:" + i;
    channel."write"(txt + g_endl);//写管道
    g_puts(txt);
    g_sleep_s(1);
}
g_puts();
channel."write"(g_noop_true);//发送管道关闭信号

Screenshot 108


Screenshot 107

Screenshot 106

Screenshot 107

** Online Compiler Example I: Hanoi **

hanoi.txt

import "user.base";
var move = func ~(i, x, y) ->
    g_puts(g_to_string(i) + ": " + g_to_string(x) + " -> " + g_to_string(y));
var h = call (func ~(f) ->
    call (func [
    "实现Y Combinator",
    "Y = f -> (x -> f x x) (x -> f x x)",
    "相关网页——https://www.cnblogs.com/bajdcc/p/5757410.html"
    ] ~(h) -> h(h))(
        lambda(x) -> lambda(i, a, b, c) ->
            call (f(x(x)))(i, a, b, c)))
(lambda(f) -> lambda(i, a, b, c) {
    if (i == 1) {
        move(i, a, c);
    } else {
        f(i - 1, a, c, b);
        move(i, a, c);
        f(i - 1, b, a, c);
    }
});
h(3, 'A', 'B', 'C');

Online Documentation

Screenshot 105

Screenshot 102

Screenshot 103

Back-end

api.txt


2. Java NIO

URTest.txt

Screenshot 101

User mode Screenshot 100

LINQ Example

URTest.txt

Bash Example

URTest.txt

Tail optimization (尾递归优化)

var g_tail_opt = func ["尾递归优化"] ~(fun, args) {
    var x = lambda(a) { throw a; };
    var fact = fun(x);
    for (;;) {
        try {
            return g_call_apply(fact, args);
        } catch (e) {
            args := e;
        }
    }
};

// Usage
g_printn("Factorial(10) = " + g_tail_opt(
    lambda(f) -> lambda(n, total) -> n <= 1 ? total : f([n - 1, total * n]),
    [10, 1]));
g_printn("Fibonacci(10) = " + g_tail_opt(
    lambda(f) -> lambda(n, a, total) -> n <= 1 ? total : f([n - 1, total, a + total]),
    [10, 0, 1]));

0. Class (Omitted 省略)

URTest.txt

1. Lambda: Y Combinator of Hanoi (见上面的例子)

Hidden, see Online Compiler Example I: Hanoi above.

2. Lambda: Trampoline (Omitted 省略)

3. List: LinkedList (Omitted 省略)

4. Multi-Process: Pipe (Omitted 省略)

5. Multi-Process: Consumer-Producer Model (生产者-消费者模型)

See online compiler example above. 见上面的例子。

6. Multi-Process: PC and Router (多进程,Omitted 省略)

7. Functional programming (函数式编程)

ModuleFunction.txt

以上省略的内容可见此README的历史版本。

Screenshot

Screenshot 1 - Code Screenshot 1

Screenshot 2 - Results Screenshot 2

Screenshot 3 - Y-Combinator Screenshot 3

Screenshot 4 - OS Virtual Machine with GUI Screenshot 4

Screenshot 5 - Remote window Screenshot 5

Screenshot 6 - Functional programming Screenshot 6

Screenshot 7 - 哲学家就餐

专栏:https://zhuanlan.zhihu.com/p/29008180

Screenshot 7

Screenshot 8 - LISP

专栏:https://zhuanlan.zhihu.com/p/29243574

Screenshot 8

Screenshot 9 - 网络流

专栏:https://zhuanlan.zhihu.com/p/32692408

Screenshot 9

jminilang's People

Contributors

bajdcc avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.