UNPKG

@lcap/nasl-parser

Version:

Take Nasl text to Nasl AST with the help of generalized parsing.

250 lines (196 loc) 6.38 kB
## 仓库目录结构 ``` ./grammar 语法文件 ./ts 解析器源码 ./ts/toAST 到 AST 的转换源码 -----decorated-nasl-ast 给 NASL 增加了一些必要的中间态字段定义 -----builtin-namespace 目前是内置函数定义 -----to-nasl-xxx 语法树到 AST 的初始转换 -----resolve-global-bindings 收集类型函数等的全局定义 -----resolve-local-bindings 处理逻辑局部的 name resolution -----process-annotations 处理注解 ./examples/unit ----- e2e 单测的 NASL 文件 ----apps 整个应用的 e2e 的 NASL 文件 ----enums 枚举的 e2e 的 NASL 文件 ----structs 数据类型的 e2e 的 NASL 文件 ----logics的 逻辑的 e2e 的 NASL 文件 ./tests/e2e ---- logics e2e 单测的 .spec.ts 文件,远端不存储,每次测试重新生成 ---- controlled e2e 单测的 控制组 nasl.json 文件 ---- real e2e 单测的 实际 nasl.json 文件,远端不存储,每次测试重新生成 ./tests/semantics 一些语义测试,会执行 toAST ./tests/unambiguous-grammar 大量语法测试,不执行 toAST,主要检测语法是否正确,语法树是否唯一 ``` ## package.json 命令 1. 编译语法和 ts 文件:`npm run build` 2. 运行所有测试文件:`npm run test-all` 3. 快速测试:`npm run test-parse`,会运行 `ts/testParse.ts` 文件,解析里面的 testCode 字符串,更换字符串内容即可测试 4. `ts/index.ts` 里面有个 `parseToNaslJson` 函数,接受字符串,产出 nasl JSON 的字符串,可作为接口调用。 `gen-predicate`:一个过时的东西,之后会尽快替换掉。 ## 测试用例摘取(特性和语法) 用例 1 ``` namespace app { namespace dataSources { namespace defaultDS { namespace entities { entity LCAPUserDeptMapping() { let userId: Integer; let deptId: Integer; } } } } } using app::dataSources::defaultDS::entities; // 引入了 LCAPUserDeptMapping // 这是一段注释 @( description = "这是一段描述", ) logic aiTest1(list: List<Integer>) => result { let userDeptMapList: List<LCAPUserDeptMapping> result = null if (list.length == 0) { result = null } else { result = ListSum(list) / list.length } } ``` 用例 2 ``` // 这是一段注释 @( description = "这是一段描述", ) logic aiTest1(list: List<Integer>) => result { let userDeptMapList: List<app::dataSources::defaultDS::entities::LCAPUserDeptMapping> // 直接使用类型全称,硬编码支持 result = null if (list.length == 0) { result = null } else { result = ListSum(list) / list.length // 内置函数硬编码支持,调用优先解析到内置函数 } end } ``` 用例 3 ``` @( description = "获取所有的角色名称", ) logic LCAPGetRoleNameList(roleName: String) => result { let search: List<app::structures::LCAPRole> if (HasValue(search)) { result = ListTransform(search, { item => item.name }) } else { result = []: List<String> } result = ListTransform(result, { item => ToLower(item) }) if (HasValue(roleName)) { if (Contains(result, ToLower(roleName))) { Add(result, roleName); } else { } } else { } ListDistinct(result) } ``` 用例 4 ``` namespace app { namespace enums { @(description = '这不是一个有用的枚举') enum MyEnumInt { @(label = 'nmb') case 0; @(label = '2333') case 1; } } } namespace WhatEverDoesNotMatter { @(description = '这是一个垃圾枚举') enum MyEnumStr { @(label = '值J') case J; @(label = '值K') case K; } } using app::enums; using WhatEverDoesNotMatter; @( transactional = false, ) logic enumRef() { let variable1: MyEnumInt; let variable2; let variable3; let variable4; let variable5; let variable6; let variable7; variable1 = MyEnumInt::0 variable2 = MyEnumInt::1 variable3 = MyEnumStr::J variable4 = MyEnumStr::K variable5 = EnumItemToStructure(MyEnumStr::J) variable6 = EnumItemToText(MyEnumInt::0) end } ``` 用例 5 ``` logic newComp() { let variable1; let variable2; variable1 = app::structures::SS1 ( // 暂时用 () 不用 {},构造器会生成到 New + 连线 property1=null, property2=111, ) variable2 = app::dataSources::defaultDS::entities::Entity1 ( // 暂时用 () 不用 {},构造器会生成到 New + 连线 id=222, createdTime=null, updatedTime=null, createdBy='fanzheng', updatedBy='bushini', property1='fanzheng1', property2='bushini1', ) end } ``` 用例 6 ``` @( description = '请输入数据结构描述' ) struct SS2 { let property1: Integer = 0; let property2: app::structures::SS1; } struct SS1 { let property1: app::structures::SS2; let property2: Decimal = 0.1; } ``` ## 添加测试用例 ### e2e 用例 1. `examples/unit/???/` 文件夹下添加 nasl 文件 2. `tests/e2e/???/controlled` 文件夹下添加正确的 json 文件 3. `ts/prepare-tests.ts` 文件里添加测试用例名 4. `npm run test-all` 看效果 举例: 1. `examples/unit/logics/asgn.nasl` 2. `tests/e2e/logics/controlled/asgn.json` 3. `ts/prepare-tests.ts` 文件里的 `logicUTNames` 数组里添加 `asgn` 4. 运行 注意,现在 NASL 各种 `undefined`、`null`、`[]` 在各个节点表现不同,很难弄一致,还有很多脏数据,除了手动控制用例外,还可以修改 `ts/nasl-json-util.ts`里面的配置,跳过一些属性的对比。 ### 解析器 parser 用例 写一个 `.spec.ts` 文件放到 `tests/unambiguous-grammar/` 文件夹下即可,文件格式直接参考其他用例 ### toAST 语义分析用例 写一个 `.spec.ts` 文件放到 `tests/semantics/` 文件夹下即可,文件格式直接参考其他用例。 ## 报错 报错?2 周写的东西,报错是不存在的。语法有问题直接群里找开发者吧。