@ abapify/ acds (中文(简体) )
ABAP CDS 源代码解析器 – 为基于 DDL 的 ABAP 源类型,设置了指示器,解析器并打入了 AST .
概览
参数 .acds (ABAP CDS DDL)源代码被打入一个完全打入的抽象语法树. 建造在 雪佛兰 快速的,错误的恢复解析.
支持的定义
| CDS 构造 | AST 节点 | 示例 |
|---|---|---|
| 图表 | TableDefinition | define table [entity] ztable { ... } |
| 根相表内. | TableDefinition | define root table entity ztable { ... } |
| 结构 | StructureDefinition | define structure zstruct { ... } |
| 简单类型 | SimpleTypeDefinition | define type ztype : abap.char(10); |
| 查看实体 | ViewEntityDefinition | define [root] view entity zv as select ... |
| 遗产视图 | ViewEntityDefinition | define view zv as select ... (单位:千美元)legacy(中文(简体) ) |
| 抽象实体 | AbstractEntityDefinition | define abstract entity zae { ... } |
| 自定义实体 | CustomEntityDefinition | define custom entity zce { ... } |
| 外部实体 | ExternalEntityDefinition | define external entity zee { ... } with federated data provided at runtime; |
| 表格函数 | TableFunctionDefinition | define table function ztf returns { ... } |
| Scalar 函数 | ScalarFunctionDefinition | define scalar function zsf ... |
| 等级 | HierarchyDefinition | define hierarchy zh as parent child hierarchy(...) { ... } |
| 侧面 | AspectDefinition | define aspect za { ... } |
| 注释 | AnnotationDefinition | define annotation za: Boolean; |
| 准入政策 | AccessPolicyDefinition | define accesspolicy zap { ... } |
| 服务 | ServiceDefinition | define service zsvc { ... } |
| 延长 | ExtensionDefinition | extend view entity zv with { ... } |
| 元数据分机. | MetadataExtension | annotate entity ZView with { ... } |
| 角色(DCL) | RoleDefinition | define role zr { grant select ... } |
解析器特性
- 错误恢复 ——在无效输入上返回部分 AST + 结构错误
- 完全注释支持 - 字符串、enums、布尔斯、数字、数组、对象
- 内建类型 —— 说
abap.char(10), (中文(简体) ),abap.dec(11,2), (中文(简体) ),abap.dats等 (中文(简体) ). - 命名类型 数据要素和有保留的名称参考
- 包含指令 —— 说
include <structure>带有可选后缀 - 评论 ——行(
//, (中文(简体) ),--)和块(/* */注释被跳过 - 不区分大小写的关键字 —— 说
DEFINE VIEW ENTITY财务报告和审定财务报表define view entity双解析; 标识符保留其原始拼写 - 从条款中 加入链条,参数化来源,来自协会
- 查看风味 —— 说
define view entity <name>遗产define view <name> - 投影元素 - 路径、电话(
coalesce(a, b), (中文(简体) ),sum(x)和cast(x as type [preserving type])
安装
bun add @abapify/acds
快速启动
import { parse } from '@abapify/acds';
const result = parse(`
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
define table ztable {
key mandt : abap.clnt not null;
key field1 : abap.char(10) not null;
field2 : some_data_element;
}
`);
if (result.errors.length === 0) {
const table = result.ast.definitions[0]; // TableDefinition
console.log(table.kind); // 'table'
console.log(table.name); // 'ztable'
console.log(table.members); // [FieldDefinition, FieldDefinition, ...]
console.log(table.annotations); // [Annotation, Annotation]
}
API 密码
parse(source: string): ParseResult
通过整个管道解析一个 CDS 源字符串: 给 = 解析 = 访问 .
interface ParseResult {
/** The parsed AST (may be partial if there are errors) */
ast: CdsSourceFile;
/** Lexing and parsing errors */
errors: CdsParseError[];
}
AST 类型
根号
interface CdsSourceFile {
definitions: CdsDefinition[];
}
type CdsDefinition =
| TableDefinition
| StructureDefinition
| SimpleTypeDefinition
| ViewEntityDefinition
| AbstractEntityDefinition
| CustomEntityDefinition
| ExternalEntityDefinition
| TableFunctionDefinition
| ScalarFunctionDefinition
| HierarchyDefinition
| AspectDefinition
| AnnotationDefinition
| AccessPolicyDefinition
| ServiceDefinition
| ExtensionDefinition
| MetadataExtension
| RoleDefinition;
定义
interface TableDefinition {
kind: 'table';
name: string;
annotations: Annotation[];
members: TableMember[]; // FieldDefinition | IncludeDirective
}
interface StructureDefinition {
kind: 'structure';
name: string;
annotations: Annotation[];
members: TableMember[];
}
interface SimpleTypeDefinition {
kind: 'simpleType';
name: string;
annotations: Annotation[];
type: TypeRef;
}
interface ServiceDefinition {
kind: 'service';
name: string;
annotations: Annotation[];
exposes: ExposeStatement[];
}
interface MetadataExtension {
kind: 'metadataExtension';
entity: string;
annotations: Annotation[];
elements: AnnotatedElement[];
}
字段类型( T)
interface FieldDefinition {
annotations: Annotation[];
name: string;
type: TypeRef;
isKey: boolean;
notNull: boolean;
}
type TypeRef = BuiltinTypeRef | NamedTypeRef;
// abap.char(10), abap.dec(11,2)
interface BuiltinTypeRef {
kind: 'builtin';
name: string;
length?: number;
decimals?: number;
}
// Data element or qualified name
interface NamedTypeRef {
kind: 'named';
name: string;
}
说明
interface Annotation {
key: string;
value: AnnotationValue;
}
type AnnotationValue =
| { kind: 'string'; value: string }
| { kind: 'enum'; value: string } // #TRANSPARENT → 'TRANSPARENT'
| { kind: 'boolean'; value: boolean }
| { kind: 'number'; value: number }
| { kind: 'array'; items: AnnotationValue[] }
| { kind: 'object'; properties: AnnotationProperty[] };
来自条款(视图实体)
interface ViewEntityDefinition {
kind: 'viewEntity';
name: string;
annotations: Annotation[];
legacy?: boolean; // true for the legacy `define view <name>` syntax
root?: boolean; // `define root view entity`
writable?: boolean; // `define writable view entity`
providerContract?: string; // `provider contract transactional_query`
sourceKind: DataSourceKind; // 'select' | 'projection'
distinct?: boolean; // `select distinct`
source: DataSource; // the root data source
joins: JoinClause[]; // ordered join chain — empty when there are no joins
fromAssociations?: AssociationDeclaration[]; // associations of the FROM region
aspectBindings?: AspectBinding[]; // `bind aspect` bindings
parameters: ParameterDefinition[];
members: ViewMember[];
where?: Expression;
groupBy?: string[];
having?: Expression;
setOperations?: SetOperation[]; // union/intersect/except branches
}
interface DataSource {
name: string;
alias?: string;
parameters?: DataSourceParameter[]; // parameterized source
}
interface DataSourceParameter {
name: string; // e.g. 'P_StartDate'
value: string; // raw binding: ':P_Key1StartDate', '$session.client', "'X'"
}
type JoinType = 'inner' | 'leftOuter' | 'rightOuter' | 'fullOuter' | 'cross';
// Conditioned joins always carry an ON condition — the grammar enforces it.
interface ConditionedJoinClause {
kind: 'join';
joinType: 'inner' | 'leftOuter' | 'rightOuter' | 'fullOuter';
source: JoinSource; // DataSource | JoinGroup
on: Expression; // the ON condition (opaque)
cardinality?: WordCardinality; // `many to one join` / `to one join`
}
// A cross join never carries an ON condition.
interface CrossJoinClause {
kind: 'join';
joinType: 'cross';
source: JoinSource;
}
type JoinClause = ConditionedJoinClause | CrossJoinClause;
// A join source is either a plain data source or a parenthesized group.
type JoinSource = DataSource | JoinGroup;
// `join (A join B on …) on …` — the group acts as a single join source.
interface JoinGroup {
kind: 'joinGroup';
source: JoinSource; // nested — may itself be a group
joins: JoinClause[]; // the join chain inside the parentheses
}
支持的加盟拼写( 正规化为 JoinType:
| 拼写 | joinType | 页:1 |
|---|---|---|
JOIN | inner | |
INNER JOIN | inner | |
LEFT JOIN | leftOuter | OUTER 可选 |
LEFT OUTER JOIN | leftOuter | |
RIGHT JOIN | rightOuter | OUTER 可选 |
RIGHT OUTER JOIN | rightOuter | |
FULL JOIN | fullOuter | OUTER 可选 |
FULL OUTER JOIN | fullOuter | |
CROSS JOIN | cross | 不得携带 ON 条件 |
这个 ON 条件 所需经费 内外结合和 不允许
对于一个十字架的加入——语法执行这一点.
已接受的加入语法对每种视图风味都是一样的: 一个 CDS 视图实体
(单位:千美元)define view entity)和经典 SQL 视图 (define view完全接受
同样的拼写. FULL [OUTER] JOIN 是 SQL 标准全外加- 它是
不属于ABAP CDS DDL 加入语法,但被支持为 HANA CDS /
CAP CDS 源( 使用标准的 SQL 加入语法) 可以随读
同样的解析器.
示例
const { ast } = parse(`
define view entity ZC_Cube as select from I_Item as _Item
left outer join ZI_Other as _Other
on _Item.key = _Other.key
association [0..1] to I_Product as _Product
on $projection.Product = _Product.Product
{
key _Item.key
}
`);
const view = ast.definitions[0] as ViewEntityDefinition;
view.joins[0].joinType; // 'leftOuter'
view.joins[0].source.alias; // '_Other'
view.fromAssociations?.[0].target; // 'I_Product'
错误
interface CdsParseError {
message: string;
line: number;
column: number;
offset: number;
length: number;
}
建筑
Source string
→ CdsLexer (Chevrotain Lexer) tokens.ts
→ CdsParser (Chevrotain CstParser) parser.ts
→ CdsVisitor (CST → AST) visitor.ts
→ CdsSourceFile ast.ts
| 模块 | 责任 |
|---|---|
tokens.ts | 托肯定义(关键词、符号、文字) |
parser.ts | 语法规则(科技委生产) |
visitor.ts | 科技委 + 类型 AST 转换 |
ast.ts | AST 节点类型定义 |
errors.ts | 错误正常化( lex + 剖析) |
index.ts | parse() 入境点+再出口 |
路线图
- ✅ DDL 数据: 表格、结构、简单类型、视图实体(
define [root] view entity,投影视图+provider contract),遗产define view,抽象/海关/表/外部实体,表/表函数,等级,方面(DRAS),DDLA注释定义,访问政策,服务(SRVD),元数据扩展(DDLX),extend view/entity表格、参数、关联、组成 - ✅ DCL 电话:角色定义 -
switchable+where, (中文(简体) ),with optional elements, (中文(简体) ),combination mode and|or|redefinition, (中文(简体) ),inherit, (中文(简体) ),inheriting conditions - ✅ 说明: 完整值语法(字符串、enums、布尔斯、数字、数组、对象、点键)
- ✅ 工具: AST行人助手,语义验证员(
SemanticDiagnostic),语法覆盖元数据 - ✅ 从条款中: 加入链条(
inner, (中文(简体) ),left [outer], (中文(简体) ),right [outer], (中文(简体) ),full [outer], (中文(简体) ),cross),以词源为主并被分组加入,参数化来源,来自协会,路径表达数据来源(_assoc[ ... ], (中文(简体) ),bind aspect - ✅ 要件数字 :
case … end,算术,铸造,调用(包括.f()窗口over (…),路径,: localized, (中文(简体) ),: redirected to, (中文(简体) ),distinct, (中文(简体) ),where编号 :group by编号 :having, (中文(简体) ),union [all]编号 :intersect编号 :except - 🔜 表达语法 (结构化
on编号 :where树——目前不透明{ source, tokens }(中文(简体) ) - 🔜 BDEF/行为定义 (由史诗 E10 拥有)
依赖关系
chevrotain——解析器工具包(解析器+CstParser+访问器)