Skip to content

Lite AST JSON 对象

duangsuse edited this page May 10, 2018 · 16 revisions

Lite AST JSON 序列化方式 测试解析 测试 ASTDump

前言:为什么要支持 AST 的 JSON 序列化

最重要的理由是 Lite 目前使用 ohm.js 作为自己的解析器,而在 JavaJavaScript 之间使用 Android WebView 只能找到传递字符串的方法,选择一个序列化方法来传递语法树数据结构是最好的解决方案,JSON 作为 JavaScript 内建的序列化方式,是 Lite AST 最好的序列化选择

其他的理由可能是使用 JSON 能 提高已转换脚本的加载速度 ,以及进一步 模块化解释器和缩减不必要的体积 ,另外还有 ohm.js 的匹配结果和真正的 AST 还有出入,需要再次处理以构建真正的 Lite AST

字段命名风格

snake_case

包含一组数据的,不使用复数形式,尽可能不使用缩写

AST 数据结构

node 数据结构应该包含 type, source, line, column 字段,也就是说每个 AST 树节点都有自己的 类型/载入文件/行/列号信息

在 Lite 1.1 完成设计时, AST 树的组成成分(继承了 LiteNode 类):

  • compstmt: (node[])stmt
  • block: (string)block_type, (string[])arg_name, (compstmt)body

block type can be toplev, brace_block, do_block, def_block, flow_block, loop_block, scope_block

  • while_loop: (node)condition, (block)block
  • scope: (string)label, (block)block
  • index_let: (node)lhs, (node)index, (node)value
  • index: (node)lhs, (node)index
  • if: (node)condition, (block)branch_if, (elif_branch)branch_elif, (block)branch_else

elif_branch: (node)condition, (block)block

  • identifier: (boolean)is_local, (string)label
  • for_loop: (identifier)variable, (node)expression, (block)block
  • def: (identifier)label, (block)block_
  • call: (string)call_type, (node)target, (node[])args

call type can be call, index, dot_operator, call_implicit, identifier

  • assign: (identifier)label, (node)value
  • binary: (node)lhs, (string)operator, (node)rhs

binary operators: | or in & and < > <= >= != == !== === << to + - * / % ** :: as

  • unary: (node)lhs, (string)operator

unary operators: unary- ! ++ --

  • list: (node[])initializer
  • table: (kv_pair)initializer

kv_pair: (string)key, (node)value

  • value: (object)value

value can be true, false, nil, number, string

  • arrow: (node)lhs, (string)rhs, (node)value

  • return: (node)value

  • break

  • next

  • import: (string)data

  • require: (string)data

范例

@a = 2
b = "Hello"
System.out.println b
{
  "type": "block",
  "file": "example.lite",
  "line": 0,
  "column": 0,
  "block_type": "toplevel",
  "arg_name": [],
  "child_node": [
    {
      "type": "assign",
      // debugging field ommited
      "label": { type: "identifier", is_local: true, label: "a" },
      "value": { type: "value", value: 2 }
    },
    {
      "type": "assign",
      // debugging field ommited
      "label": { type: "identifier", is_local: false, label: "b" },
      "value": { type: "value", value: "Hello" }
    },
    {
      "type": "call",
      "call_type": "call_easy",
      "target": {
        {
          "type": "call",
          "call_type": "call_index",
          "target": {
            {
              "type": "call",
              "call_type": "call_index",
              "target": {
                { "type": "call", "call_type": "identifier", "target": { "type": "identifier", "is_local": false, "label": "System" }, "args": null }
              },
              "args": [ {type: "identifier", is_local: false, label: "out"} ]
            }
          },
          "args": [ {type: "identifier", is_local: false, label: "out"} ]
        }
      },
      "args": [ {type: "identifier", is_local: false, label: "b"} ]
    }
  ]
}