UNPKG

@lcap/nasl-parser

Version:

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

120 lines (100 loc) 4.39 kB
import * as nasl from './decorated-nasl-ast'; import { isNewList, isStructure, isLogic, isFunction, isLogicDeclaration, isEnum} from '@lcap/nasl-concepts/asserts'; import { Visitor, withNoEnv } from './common-util'; import { CompilerEnvInfo } from './resolve-global-bindings'; // import { tryAddToNaslDataSource } from './process-annotations-entity'; /** * 怎么说呢,步子不能迈太大,还是分三步吧。 * 1. 编译器内置一批可用的注解和处理规则,这样 AI 就能用起来了 * 2. 编译器给一套规范和一个入口,用户可用 ts、js 写处理规则,编译器会调用用户的处理规则 * 3. 用户可用 nasl 文本语法写处理规则 * * 发现一个用构造函数 @column(id = ..., name = ..., required = ...)相比于 @id =..., @name =... @required =... 的好处 * 用构造函数的话,可以为 id、name、required 都设默认值,所以 @column 可以不写这些参数。 * 如果不用构造函数的话,即便要用默认值,@id@name@required 也都必须写出来,因为一般来说如果用户不标记,也不能认为有一批默认的标记吧 */ // processAnnotations -> tryAddToNaslDataSource -> addToSpecificNaslDataSource -> toNaslDataEntity -> processColumnAnnotation export function processAnnotations(cei: CompilerEnvInfo, nodes: Array<nasl.SupportedDefinition>, dataSources: any[]) { new Visitor().preOrderVisitAll(cei, nodes, withNoEnv(processLogicAnnotations)); new Visitor().preOrderVisitAll(cei, nodes, withNoEnv(processEnumAnnotations)); new Visitor().preOrderVisitAll(cei, nodes, withNoEnv(processStructAnnotations)); // @ts-ignore // nodes = new Visitor().preOrderVisitAll(cei, nodes, withNoEnv(tryAddToNaslDataSource(dataSources))); } const IDE = 'ide'; const DISPLAY = 'display'; export function processLogicAnnotations(nl : nasl.Logic | nasl.Function) { if (!isLogic(nl) && !isFunction(nl) && !isLogicDeclaration(nl)) { return nl; } const cAnns: Array<nasl.CstAnnotation> = nl.annotations; if (cAnns) { cAnns.forEach(cAnn => { cAnn.value.forEach(ann => { nl[ann.name] = (ann.value as nasl.StringLiteral).value; }); }); } return nl; } export function processEnumAnnotations(ne: nasl.Enum) { if (!isEnum(ne)) { return ne; } const cAnns: Array<nasl.CstAnnotation> = ne.annotations; if (cAnns) { cAnns.forEach(cAnn => { cAnn.value.forEach(ann => { ne[ann.name] = (ann.value as nasl.StringLiteral).value; }); }); } ne.enumItems.forEach(processEnumItemAnnotations); return ne; function processEnumItemAnnotations(ei: nasl.EnumItem) { const cAnns: Array<nasl.CstAnnotation> = ei.annotations; if (cAnns) { cAnns.forEach(cAnn => { cAnn.value.forEach(ann => { ei[ann.name] = ann.value; if (ann.name === 'label') { ei.label = new nasl.StaticString({value: (ann.value as nasl.StringLiteral).value}); // 厉害啊! } }); }); } } } export function processStructAnnotations(ns: nasl.Structure) { if (!isStructure(ns)) { return ns; } const cAnns: Array<nasl.CstAnnotation> = ns.annotations; if (cAnns) { cAnns.forEach(cAnn => { cAnn.value.forEach(ann => { ns[ann.name] = (ann.value as nasl.StringLiteral).value; }); }); } ns.properties.forEach(processStructPropertyAnnotations); return ns; function processStructPropertyAnnotations(sp: nasl.StructureProperty) { const cAnns: Array<nasl.CstAnnotation> = sp.annotations; if (cAnns) { cAnns.forEach(cAnn => { cAnn.value.forEach(ann => { if (ann.name === 'label') { sp.label = (ann.value as nasl.StringLiteral).value; // 厉害啊! } }); }); } } } // @ts-ignore export const forceToString = (e: AnnArgVal) => (e as StringLit).val; // @ts-ignore export const forceToBoolean = (e: AnnArgVal) => (e as BooleanLit).val; // @ts-ignore export const forceToNumber = (e: AnnArgVal) => (e as IntegerLit | DecimalLit).val;