首页 > 编程语言 >Go动态解析文本,实现算术表达式计算、弱类型编程语言技巧

Go动态解析文本,实现算术表达式计算、弱类型编程语言技巧

时间:2022-11-02 15:02:44浏览次数:87  
标签:src 编程语言 10 lit print Lit 输出 Go 表达式


## 纯Go语言开发了一个轻量级解释型语言 Lit

最近业余时间闲来无事,我就尝试一下自己开发一个轻量级的解释型语言。
几年前我一直是用php,它有时候确实很顺手,但有时候又很不严谨,没有原则性,所以整体你会感觉它非常臃肿。
出于学习的目的,我目前已经利用业余时间开发了一个多月,目前实现了变量声明,内置函数调用、算术表达式(这个最难了)等,其余功能仍然在持续迭代中。

github 地址 : https://github.com/pywee/lit

暂且我将这个语言命名为 Lit,以下是我已经实现的特性,仍然有一些小bug需要持续修复,感兴趣的话给个 star.


---

#### 使用方法


```
go get github.com/pywee/lit
```

 

**一、支持变量声明**

import "github.com/pywee/lit"

func main() {
// 执行以下句子,最终会输出
src := []byte(`
a = 123;
b = a + 456;
print(b); // 579
`)
_, err := lit.NewExpr(src)
}

 

---

**二、算术表达式的计算。算术符号的优先级保持与 Go 语言相同。请看示例:**

// 不同的语言符号优先级是不完全一样的,Lit 的算术符号优先级保持与 Golang 一致
// 首先我们执行 Go 语言原生函数进行数学表达式计算
// 以下句子最终会输出
// +1.600000e+001
// 125
println((2 + 100 ^ 2 - (10*1.1 - 22 + (22 | 11))) / 10 * 2)
println(12/333+31+(5/10)-6|100)

// 使用 Lit 计算文本中的数据
// 表达式文本
// 执行下面的句子 最终会输出
exprs := []byte(`
a = (2 + 100 ^ 2 - (10*1.1 - 22 + (22 | 11))) / 10 * 2;
b = 12 / 333 + 31 + (5 / 10) - 6 | 100;
print(a); // 16
print(b); // 125
`)
_, err = lit.NewExpr(exprs)

// *** 同样的表达式放在 PHP 中,会输出 -24 ***

 

**三、当前已支持部分常用内置函数(测试阶段),更多的内置函数我将在接下来继续完成**

// 下面的句子调用了两个函数
// isInt(arg) 用来检查 arg 是否为整型
// replace(arg1, arg2, arg3, arg4) 用来做字符串替换

// 执行下面语句 最终会输出
exprs := []byte(`
a = replace("hello word111", "1", "", 2-isInt((1+(1 + isInt(123+(1+2)))-1)+2)-2);
varDump(a); // STRING hello word
`)
_, err = lit.NewExpr(exprs)

  

**四、弱类型转换,弱类型的这一特性我将它设计为与 PHP 基本一样**

// 当布尔值参与运算时,底层会将 true 转为 1, false 转为 0
// 执行下面句子 将输出
src := []byte(`
a = true - 1;
b = isInt(1);
c = isFloat(1);
d = false == 0.0;
e = "false" == 0.0;
print(a); // 0
print(b); // true
print(c); // false
print(d); // true
print(e); // true
`)
_, err := lit.NewExpr(src)


// 与其他弱类型语言一样
// 字符串数字与整型相操作,在 Lit 的底层会将字符串数字转换为整型
// 执行下面句子 将输出
src := []byte(`
a = "1" - 1;
b = 0.0 >= false+1 || (1<=21 && 1==1);
print(a); // 0
print(b); // true
`)
_, err := lit.NewExpr(src)


// 与其他弱类型语言一样
// 字符串数字与整型相操作,在 Lit 的底层会将字符串数字转换为整型
// 执行下面句子 将输出
src := []byte(`
a = "1" - 1;
print(a); // 0
`)
_, err := lit.NewExpr(src)


// 字符串与字符串相加时 将进行字符串的拼接
// 执行以下句子,将会输出
src := []byte(`
a = "abc" + "def";
print(a); // abcdef
`)
_, err := lit.NewExpr(src)


// 但如果当两个字符串都为数字时 对他们进行相加 则会被底层转换为数字
// 执行如下句子,将会输出
src := []byte(`
a = "123" + "456";
print(a); // 579
`)
_, err := lit.NewExpr(src)


// 其他字符串+整型将会报错
// 执行如下句子
src := []byte(`
a = "abcwwww1230"+0.01;
print(a); // 报错
`)
_, err := lit.NewExpr(src)

  

**五、"并且" 与 "或者" 符号处理**

// 执行如下句子,将会输出
src := []byte(`
a = isInt(1) && 72+(11-2) || 1-false;
varDump(a); // BOOL true
`)
_, err := lit.NewExpr(src)

  

**六、自定义函数处理 (迭代中)**

// 执行如下句子,将会输出
// 8 123
src := []byte(`
a = "123";
func max(b = 10, m = "2") {
print(b - m, a);
}
max(); // 8 123
`)
_, err := lit.NewExpr(src)

  

**请注意,Lit 的算术符号优先级向 Golang 看齐。每个语言对算术符号的优先级处理都有一定区别,如,针对以下表达式进行计算时:**

// 2 + 100 ^ 2 - (10*1.1 - 22 + (22 | 11)) / 10 * 2
// PHP 输出 -104
// Node.js 输出 -104
// Golang 输出 96
// Lit 输出 96

  

**Lit 算术符号优先级**

第一级 ```() && || ```

第一级 ```> < >= <= == != ===```

第三级 ```* / % ```

第四级 ```| &```

第五级 ```+ - ^ ```

---

**当前支持的内置函数有如下,更多函数将会在逐步补充**

// 通用处理函数
print
varDump

// 字符串处理函数
// 函数的命名基本参考了 Go 语言
// 除了个别函数有差别,如
// utf8Len 用于检测字符串字数的函数
// isNumeric 用于判断当前输入是否为数字
trim
trimLeft
trimRight
trimSpace
len
utf8Len
md5
replace
contains
index
lastIndex
toLower
toUpper
toTitle
repeat

// 其他函数
isNumeric
isBool
isInt
isFloat

  

github 地址: https://github.com/pywee/lit

标签:src,编程语言,10,lit,print,Lit,输出,Go,表达式
From: https://www.cnblogs.com/pywee/p/lit.html

相关文章

  • 正则表达式
    正则表达式的概述1、概念正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。正则表达式是对字符串(包括普通字符(例如,a到z之间的字母)和特殊字符(称为“元字......
  • golang中的错误处理
    0.1、索引https://waterflow.link/articles/16667167272361、panic当我们执行panic的时候会结束下面的流程:packagemainimport"fmt"funcmain(){ fmt.Println("......
  • 23.MongoDB地理位置检索
    MongoDB地理位置检索一、查询当前坐标附近的目标@TestpublicvoidqueryNear(){//1.以当前位置的经纬度为圆点GeoJsonPointpoint=newGeoJ......
  • 在maven的web项目的test的文件执行main方法报错Failed to execute goal org.codehaus.
    在pom.xml添加这个插件<build><plugins><plugin><groupId>org.codehaus.mojo</groupId><artifactId>exec-maven-plugin</artifactId......
  • vscode配置Go开发环境
    这篇文章主要介绍了手把手教你vscode配置golang开发环境的步骤,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下 1.下载安......
  • Golang获取http Request内容
    获取httpRequest内容获取httpRequest的内容,需要io.ReadAll调用读取了request的Body,读取完后,我们的控制器就没有请求内容了,此时应该需要把读取出来的字节重新构造成一个R......
  • 如何简单理解正则表达式?只需1分钟就可以看到她优美的舞姿
    Hi,大家好,本章节开始将会从零开始和大家用图文的方式,让你从零基础学会正则表达式!有兴趣的小伙伴可以持续关注我,或者在专栏中进行查看自我学习,愿与君携手前行!本文将要说到的正......
  • go永久阻塞
    用Go语言做一个永久阻塞,你有哪些小技巧?Go语言圈 2022-11-0208:30 发表于广东学习与交流:Go语言技术微信群商务合作加微信:LetsFenggoland全家桶激活码,支持所有版......
  • 使用golang操作mongodb
    背景学习使用golang操作mongodb,主要是常见的增删改查。代码packagemainimport("context""fmt""log""go.mongodb.org/mongo-driver/bson"......
  • MongoDB随记
    正常情况下MongoDB的db就是mysql里的库;而collection就是mysql里的表(MongoDB的表名可以是用.分隔,比如aaa.bbb;但是注意自定义表不能以system.aaa格式);然后可视化工具在表名......