#语言 #解析器

leap-lang

Leap语言解析器

6个版本

0.3.0 2022年7月19日
0.2.0 2022年3月18日
0.1.3 2021年9月24日
0.1.2 2021年7月18日
0.1.1 2021年6月2日

#208 in 编程语言

每月 27次下载

MIT许可证

90KB
2.5K SLoC

Leap语言的解析器。

链接

Leap语言。

Leap是一种轻量级、简单的语言,用于描述数据结构。

支持的数据类型

  • str - utf-8字符串
  • int - 64位整数
  • float - 64位浮点数
  • bool - 布尔类型
  • list - 值数组
  • struct - 包含字段的用户定义类型
  • enum - 包含多个变体的用户定义类型

命名

所有用户定义的名称都使用短横线命名法(所有字母均为小写,用短横线分隔),例如:user-autharticle-titlesome-long-long-long-name

  • 名称应以字母开头,可以包含数字
  • 名称中的单词用单个短横线分隔

列表

列表定义值数组,并接受单个类型参数作为元素类型

  • list[int] - 整数列表
  • list[user] - user结构体的列表
  • list[list[string]] - 字符串列表的列表

结构体

结构体是用户定义的类型,可以有一个或多个字段,可以为泛型值提供类型参数。

示例

.struct user
    name: str
    age: int
    address: str
    tags: list[str]
    active: bool

这里 user.name 是字符串,而 user.tags 是字符串列表

无字段的空结构体

.struct none

带有类型参数的结构体

.struct some[t]
    value: t

这里 t 是类型参数,如果将其应用于 str,则 value 将成为 str

枚举

枚举是用户定义的类型,它描述了它可以具有哪些变体,只有结构体可以是枚举的变体,枚举可以具有类型参数。

示例

.enum response
    user
    none

这里 response 可以是 usernone 结构体。

变体可以有名称。

.enum account
    admin: user
    customer: user

在这里,变体名称可以避免命名冲突,因为变体 admincustomer 使用相同的类型 user

带有类型参数的枚举

.enum option[t]
    some[t]
    none

这里 t 是类型参数,如果它被应用于 int,则 some[t] 变体会变为 some[int]

类型参数

类型可以为泛型值拥有类型参数。如果有多个类型参数,它们通过空格分隔

.struct some-struct[a b c]
    value-a: a
    value-b: b
    value-c: c
    value-d: other-struct[a b list[c]]
    value-e: some[int]

这里 abc 是类型参数,这些参数应按顺序应用于类型,例如 some-struct[int int str],在这种情况下,value-a 将具有 int 类型,而 value-d 将具有 other-struct[int int list[str]] 类型。 value-e 具有类型 some[int],这是将 t 应用为 intsome[t]

注释

注释以 /-- 开始,可以放在单独的一行,或者放在行的末尾

/-- some comment about page struct
.struct page[t]
    items: list[t] /-- other comment about items of page
    /-- comment about page additional info
    total-count: int

示例

让我们为博客引擎的 REST API 建模类型

/-- general types
.struct none

.struct some[t]
    value: t

.enum option[t]
    none
    some[t]

.enum result[t e]
    ok: some[t]
    err: some[e]

/-- api types
.struct page[t]
    value: t
    total-count: option[int]

.struct user
    id: int
    name: str
    email: str

.struct article
    id: int
    author: user
    title: str
    text: str
    tags: list[str]

这里针对我们的 api

  • 对于每个请求,api 都返回 result[t str],其中 t 用于正确响应,而 str 用于错误(包含错误信息的字符串)
  • GET /users/7 将返回 result[user str],这允许在成功时获取用户信息或错误信息
  • GET /articles 将返回 result[page[article] str],这允许在成功时获取文章分页列表或错误信息
  • page.total-count 是可选的,如果 total-count 未知,它将等于 none,否则为 some[int]

示例用法

Cargo.toml

[dependencies]
leap-lang = "0.2"

main.rs

use leap_lang::parser::parser::Parser;

fn main() {
    let types = Parser::parse("
        .enum enum1
        .struct struct1
        .struct struct2
            v1: int
    ").unwrap();
    for t in types {
        println!("name: {}", t.name());
    }
    // output:
    //
    // name: enum1
    // name: struct1
    // name: struct2
}

无运行时依赖项