npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@lcap/nasl-parser

v0.1.0

Published

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

Downloads

154

Readme

仓库目录结构

./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 各种 undefinednull[] 在各个节点表现不同,很难弄一致,还有很多脏数据,除了手动控制用例外,还可以修改 ts/nasl-json-util.ts里面的配置,跳过一些属性的对比。

解析器 parser 用例

写一个 .spec.ts 文件放到 tests/unambiguous-grammar/ 文件夹下即可,文件格式直接参考其他用例

toAST 语义分析用例

写一个 .spec.ts 文件放到 tests/semantics/ 文件夹下即可,文件格式直接参考其他用例。

报错

报错?2 周写的东西,报错是不存在的。语法有问题直接群里找开发者吧。