aml

package module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 16, 2023 License: MIT Imports: 11 Imported by: 1

README

go-bilibili-api

一种记录 Api 调用方式的文件格式的 golang 解析器。

介绍

tests 目录下有文件 user.aml

type query = {
    num mid: 目标用户mid
    bool photo: 是否请求用户主页头图 = false
}

type res<T> = {
    num code: 返回码 = 0
    str message: 返回消息
    num ttl = 1
    T data: 数据
}

type card = {
    str mid
    str name
    str face
}

type userInfo<T> = {
    T card: 查询用户的信息
    bool following: 是否关注
    num follower: 粉丝数
}

GET get_user_card: 用户名片信息 = {
    str url = https://api.bilibili.com/x/web-interface/card
    query params
    res<userInfo<card>> response
}

这个文件的格式是:每行文本称为一个 Sentence 每个 Sentence 由四部分组成,分别为 Type Name Hint Value

GET get_user_card: 用户名片信息 = {

以上面这行为例:Type=GET Name=get_user_card Hint=用户名片信息 Value={

这些参数只有 Name 是必须的,其他可以为空。

res<userInfo<card>> response

例如上面这行:Type=res<userInfo<card>> Name=response Hint="" Value=""

关键字
关键字 意义
query http请求当中的query参数,即url问号后的部分
body http请求当中的请求体参数,一般是json类型,当然也会有二进制,或者表单等格式的数据
required 指定参数是必要的
optional 指定参数是可选的
get api方法为get请求
post api方法为post请求
delete api方法为delete请求
put api方法为put请求
option api方法为option请求
head api方法为head请求
patch api方法为patch请求
enum 字段数据类型为枚举值
str 字段数据类型为字符串
num 字段数据类型为数字
auto aml会自动推导数据类型,默认为字符串
bool 布尔值,即true 或者false
import 导入其他文件当中的类型定义
from 指定导入来源
deprecate 指定参数被弃用
编写接口
GET get_user_card: 用户名片信息 = {
    str url = https://api.bilibili.com/x/web-interface/card
    query params
    res<userInfo<card>> response
    notice = 使用函数的注意事项
}

使用 GETPOST 作为 Type 来定义一个 Api 接口,其后的 get_user_card: 用户名片信息 是用来导出代码时会用到的函数名和注释。

接口必须使用大括号包裹 url 子语句,表示这个接口的地址。其他的子语句是可选的,例如 paramsresponse

一些与网络请求相关的字段被称为特殊字段,包含 url data params headers cookies response

除此之外都是普通字段,他们也会被导出至 .json.yml 文件中,但可能不会导出到代码中。

例如上面的 notice 字段,注意到该字段并没有显式记录类型,因此内部会根据其初始值判断类型为 str

- notice = 使用函数的注意事项
+ auto notice = 使用函数的注意事项

你也可以通过设置类型为 auto 达到同样的效果。

神奇的类型

你可能到了,上述格式中出现了非JSON数据类型(JSON数据类型strnumbool这一类)

query params
res<userInfo<card>> response

这里的 queryres<userInfo<card>> 是什么鬼啊?

type query = {
    num mid: 目标用户mid
    bool photo: 是否请求用户主页头图 = false
}

找到 query 的定义处,我们使用 type 关键字定义了这个类型,他的值是一个字典。这样我们就可以在后续语句中复用这个类型了。

- params = {
-     num mid: 目标用户mid
-     bool photo: 是否请求用户主页头图 = false
- }
+ query params

你可能也注意到了,上述语句中出现了含有尖括号 <> 的类型。没错,这就是泛型。

type res<T> = {
    num code: 返回码 = 0
    str message: 返回消息
    num ttl = 1
    T data: 数据
}

找到res的定义处,使用<>和其中的任意字符表示这个类型的泛型,泛型可用于其内部语句的类型处。

res<userInfo<card>> response使用时。response会被解析为:

response = {
    num code: 返回码 = 0
    str message: 返回消息
    num ttl = 1
    userInfo<card> data: 数据
}

参数可以多个,用 , 分隔,也就是 type res<T1,T2> = xxxres<a, b> response

从文件导入类型
# lib.aml
type query = {
    num mid: 目标用户mid
    bool photo: 是否请求用户主页头图 = false
}

type card = {
    str mid
    str name
    str face
}
# user.aml
from lib import query, card

...

GET get_user_card: 用户名片信息 = {
    str url = https://api.bilibili.com/x/web-interface/card
    query params
    res<userInfo<card>> response
}

导入别的文件里的类型就这么简单,然后可以用 * 导入全部类型:

- from lib import query, card
+ from lib import *
值有什么用

前文提到,每条语句的 Value 项并不是必须的,那么写值有什么用呢?目的是方便导出:

params = {
    num mid: 目标用户mid
    bool photo: 是否请求用户主页头图 = false
}

被导出至 python 代码时:

async def get_user_card(mid: int, photo: bool = False):
    """
    用户名片信息
    """
    pass  # 以下省略

可以发现,值的有无与函数参数中默认值有无是一致的。

如果有一个字段是固定某个值,而我又不希望导出的代码中可以在调用函数时可以修改它,可以在值的后面加上 ,constant

多行文本

当值需要写多行时,可以使用 " ' 等包裹文本:

GET get_user_card: 用户名片信息 = {
    str url = "https://api.bilibili.com/x/
web-interface/card"
}

这会被解析成 url = https://api.bilibili.com/x/web-interface/card

注意,拼接后的字符串没有换行符。

最后

之后会支持别的语言大概

贡献

相关项目

Documentation

Index

Constants

View Source
const (
	NUMBER     = iota + 4 // number
	STRING                // string
	COMMA                 // ,
	LBRACKET              // [
	RBRACKET              // ]
	LBRACE                // {
	RBRACE                // }
	LANGLE                // <
	RANGLE                // >
	LGROUP                // (
	RGROUP                // )
	AUTO                  // auto
	NUM                   // num
	STR                   // str
	TYPE                  // type
	REQUIRED              // required
	OPTIONAL              // optional
	DEPRECATE             // deprecate
	GET                   // get method
	POST                  // post method
	OPTION                // option method
	PUT                   // put method
	DELETE                // delete method
	HEAD                  // head method
	PATCH                 // patch method
	BOOL                  // bool
	FROM                  // from
	IMPORT                // import
	COLON                 // :
	IDENTIFIER            // identifier
	ASSIGNMENT            // =
)

Variables

This section is empty.

Functions

func AutoType

func AutoType(k, v string) (typ string, val any)

自动类型

func GetKind

func GetKind(result string) int

关键字

func In

func In(ls []string, v string) bool

python list in

func JsonDump

func JsonDump(v any, indent string) string

json 序列化

func NameSlice

func NameSlice(s string) (name string, args []string)

纯净类型

func NoFlag added in v0.2.0

func NoFlag() bool

未输入参数

func YamlDump

func YamlDump(v any) string

yaml 序列化

Types

type Api

type Api struct {
	// 接口地址
	Url string `json:"url" yaml:"url"`
	// 请求方式
	Method string `json:"method" yaml:"method"`
	// 函数简介
	Hint string `json:"comment,omitempty" yaml:"comment,omitempty"`
	// 函数名
	Function string `json:"function,omitempty" yaml:"function,omitempty"`
	// 接口描述
	Info *Sentence `json:"-" yaml:"-"`
	// 接口载荷
	Data *Sentence `json:"data,omitempty" yaml:"data,omitempty"`
	// 接口参数
	Params *Sentence `json:"params,omitempty" yaml:"params,omitempty"`
	// 接口请求头
	Headers *Sentence `json:"headers,omitempty" yaml:"headers,omitempty"`
	// 接口文本
	Cookies *Sentence `json:"cookies,omitempty" yaml:"cookies,omitempty"`
	// 接口返回
	Response *Sentence `json:"response,omitempty" yaml:"response,omitempty"`
}

请求任务

func NewApi

func NewApi(sentence *Sentence) *Api

构造函数

type File added in v0.2.0

type File struct {
	Name    string
	Content string
}

type Include

type Include struct {
	// contains filtered or unexported fields
}

导入

func NewInclude

func NewInclude(dir, path string, args []string) *Include

func (*Include) Need

func (i *Include) Need(s string) bool

type Lexer

type Lexer struct {
	*Scanner
	// contains filtered or unexported fields
}

词法分析器

func FromFile

func FromFile(path string) (l *Lexer)

获取文件流

func FromURL

func FromURL(url string) (l *Lexer)

获取网络流

func NewLexer

func NewLexer(path string) *Lexer

自动选择

func (*Lexer) Done

func (l *Lexer) Done() (int, string)

func (*Lexer) Next

func (l *Lexer) Next() bool

func (*Lexer) Read

func (l *Lexer) Read()

func (*Lexer) SaveNow

func (l *Lexer) SaveNow(kind int)

保存暂存和当前的字符

func (*Lexer) SaveStorage

func (l *Lexer) SaveStorage() bool

保存暂存的字符

返回是否保存成功

func (*Lexer) Shift

func (l *Lexer) Shift() *Lexer

type Parser

type Parser struct {
	// 词法分析器
	*Lexer

	// 变量类型
	Types map[string]*Sentence
	// Api 字典
	Output map[string]*Api
	// contains filtered or unexported fields
}

语法分析器

func NewParser

func NewParser(path string) *Parser

func (*Parser) Export added in v0.2.0

func (p *Parser) Export(cmds ...string) (files []File)

导出文件

cmds: 可选的必须导出参数

func (*Parser) GetDir added in v0.2.0

func (p *Parser) GetDir() string

func (*Parser) IsType

func (p *Parser) IsType() (*Sentence, bool)

判断类型

func (*Parser) Match

func (p *Parser) Match()

选择匹配

func (*Parser) MatchApi

func (p *Parser) MatchApi(typ string) error

匹配 Api

func (*Parser) MatchArgs

func (p *Parser) MatchArgs() (args []string, kind int)

匹配参数

func (*Parser) MatchImport

func (p *Parser) MatchImport() (*Include, error)

匹配导入语句

func (*Parser) MatchLength

func (p *Parser) MatchLength() (err error)

匹配类型数组长度

func (*Parser) MatchList

func (p *Parser) MatchList() (err error)

匹配列表

func (*Parser) MatchType

func (p *Parser) MatchType() error

匹配定义语句

func (*Parser) MatchVar

func (p *Parser) MatchVar(typ string) *Sentence

匹配变量

func (*Parser) NewExt added in v0.2.0

func (p *Parser) NewExt(ext string) string

type Plugin added in v0.2.0

type Plugin struct {
	Cmd         string
	Author      string
	Version     string
	Description string
	Link        string
	Generate    func(p *Parser) (files []File)
	// contains filtered or unexported fields
}

func GetLoadedPlugin added in v0.2.0

func GetLoadedPlugin() []Plugin

获取已注册插件

func (Plugin) Load added in v0.2.0

func (p Plugin) Load()

注册插件

type Scanner

type Scanner struct {
	// contains filtered or unexported fields
}

func (*Scanner) Close

func (s *Scanner) Close()

关闭文件

func (*Scanner) First

func (s *Scanner) First() string

获取暂存第一个字符

func (*Scanner) HasQuotation

func (s *Scanner) HasQuotation() bool

判断暂存是否以引号起始

func (*Scanner) Length

func (s *Scanner) Length() int

获取暂存字符长度

func (*Scanner) Next

func (s *Scanner) Next() bool

获取下位字符

func (*Scanner) Read

func (s *Scanner) Read() string

读取 string

func (*Scanner) Restore

func (s *Scanner) Restore() string

清空暂存并以 string 返回

func (*Scanner) Store

func (s *Scanner) Store()

暂存当前字符

type Sentence

type Sentence struct {
	Type  string   `json:"type,omitempty" yaml:"type,omitempty"`
	Name  string   `json:"-" yaml:"-"`
	Hint  string   `json:"hint,omitempty" yaml:"hint,omitempty"`
	Value string   `json:"-" yaml:"-"`
	Args  []string `json:"-" yaml:"-"`

	Length int64                `json:"length,omitempty" yaml:"length,omitempty"`
	Output any                  `json:"value,omitempty" yaml:"value,omitempty"`
	List   []*Sentence          `json:"-" yaml:"-"`
	Map    map[string]*Sentence `json:"-" yaml:"-"`
	// contains filtered or unexported fields
}

单条语句

其中 Args 表示其 Name 中携带的参数

当该语句为字典时 Map 不为空 表示其下包含的语句

func (*Sentence) Add

func (sentence *Sentence) Add(typ, name, hint, value string, args []string, vt map[string]*Sentence, length int64) *Sentence

添加子语句

func (*Sentence) Find

func (sentence *Sentence) Find(arg string) int

查找类型参数序号

func (*Sentence) IsApi

func (sentence *Sentence) IsApi() bool

判断该语句是否为 Api 起始语句

func (*Sentence) IsBrace

func (sentence *Sentence) IsBrace() bool

判断该语句是否为起始括号

func (*Sentence) IsBracket

func (sentence *Sentence) IsBracket() bool

判断该语句是否为起始列表

func (*Sentence) IsConstant

func (sentence *Sentence) IsConstant() bool

判断该语句是否为常量

func (*Sentence) IsDict

func (sentence *Sentence) IsDict() bool

判断该语句是否为字典

func (*Sentence) IsEnum

func (sentence *Sentence) IsEnum() bool

判断该语句是否为枚举

func (*Sentence) IsGroup

func (sentence *Sentence) IsGroup() bool

判断该语句是否为起始枚举

func (*Sentence) IsList

func (sentence *Sentence) IsList() bool

判断该语句是否为列表

func (*Sentence) IsOpen

func (sentence *Sentence) IsOpen() bool

判断该语句是否未闭合

func (*Sentence) IsOptional

func (sentence *Sentence) IsOptional() bool

判断该语句是否为选填变量

func (*Sentence) IsRequired

func (sentence *Sentence) IsRequired() bool

判断该语句是否为必要变量

func (*Sentence) Pop

func (sentence *Sentence) Pop(name string) *Sentence

移除子语句

func (*Sentence) SetOutput

func (sentence *Sentence) SetOutput(val any)

修改输出

func (*Sentence) ToDict

func (sentence *Sentence) ToDict() map[string]string

转字典

type Token

type Token struct {
	Kind  int
	Value string
}

最小词语单元

func (*Token) New

func (t *Token) New(kind int, value string)

新建

func (*Token) NotNull

func (t *Token) NotNull() bool

判空

func (*Token) Reset

func (t *Token) Reset()

清除

func (*Token) Set

func (t *Token) Set(n *Token) *Token

设置

func (*Token) Shift

func (t *Token) Shift(n *Token)

切换

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL