kotlin映射c语言指针,GitHub - bajdcc/jMiniLang: 用Kotlin实现的编译器和虚拟机,并在此基础上构建操作系统。...

jMiniLang - GLR Compiler and Virtual Machine (Kotlin)

68747470733a2f2f63692e6170707665796f722e636f6d2f6170692f70726f6a656374732f7374617475732f61786d63793167696a64627733726a393f7376673d74727565

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

编译原理(涵盖正则文法(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 philo、test 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(特性)

词法分析阶段。Lexer which generates NFA and DFA.

语法分析、词法分析、制导翻译。Parser which implements LALR(1) Grammar with optional semantic action.

语义分析。Customized semantic analysis.

可打印语法树。Printable syntax tree.

基于栈的自定义指令集。Stack-based instruction design.

Kotlin本地方法导入。Native method.

代码页导入/导出。Import and export of code page.

代码页序列化。Serializable code page.

匿名函数及闭包。Lambda functions and Closure.

语法/词法错误提示。Display grammar and semantic errors.

管道机制。Pipe.

多进程机制。Multiple process.

同步/异步执行代码。Load file with Sync/Async.

虚拟机。Virtual machine.

支持彩色界面。Support Colorful GUI.

函数式编程。Functional programming.

LISP.

网络流。Socket stream.

虚拟文件系统。Save/Load file or VFS.

基于原型的类设计。Class prototype.

Bash Interface.

数组/词典初始化。Array/Map initialize list.

异常机制。Try/Catch/Throw.

行为树。Behavior Tree, including PC network simulator.

用户级进程。RING 3 Process, including User Service, fork.

网页服务器。Web Server, including Online Compiler and Runner.

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命令)

echo

dup

pipe

grep

proc

range

task

sleep

time

count

msg

bash

replace

util

ai

pc

music

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 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

Example

Web Server

Spring Boot API, port 8080

Java NIO, port 8088

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 **

d4305c1e757a0427b92cb591f4d0bf4b.png

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);//发送管道关闭信号

91a7e81e6ae35116194f2b85ecf57972.gif

649d602b841cd1373932b60ab82344f4.gif

c48db0e835b9e5abd25d28bb5d0d9819.png

649d602b841cd1373932b60ab82344f4.gif

** Online Compiler Example I: Hanoi **

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

52dcd597ca790bff82f2462cb177f1c8.png

b5a557d76e51fa9752f35e245bdb6d5b.png

web-3.gif

Back-end

2. Java NIO

a305b33cd54f82c0ad67cf0539cfd238.png

User mode

4831bb34660be19399a2d43716280d7d.gif

LINQ Example

Bash Example

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 省略)

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 (函数式编程)

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

Screenshot

Screenshot 1 - Code

b1e2963c08805d4bb0e52297135260c0.png

Screenshot 2 - Results

b5b0f74eda5b823bb9f1ea6dc79fcedb.png

Screenshot 3 - Y-Combinator

565869094bc472a924cffbad191be705.png

Screenshot 4 - OS Virtual Machine with GUI

jMiniLang_4.png

Screenshot 5 - Remote window

74257892e3d55c846e52d4cccb84ffa2.png

Screenshot 6 - Functional programming

zhihu-2.png

Screenshot 7 - 哲学家就餐

235986fbc9d4477fb190670a2bc3c0a3.png

Screenshot 8 - LISP

d3d73a19cb1d752d9b5d210e25b16447.png

Screenshot 9 - 网络流

30d20e32a35442014d726e4cf680ac85.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值