news 2026/5/15 18:44:50

请举例 AST 的更多真实例子

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
请举例 AST 的更多真实例子

请举例 AST 的更多真实例子

下面给你几个更真实、更接近解析器输出的 AST 例子(我会用“代码片段 → AST(树形/括号式)→ 可能的序列化”来展示)。为了可读性,我会给精简但结构真实的 AST(类似 Tree-sitter / ESTree / Python ast 模块的风格),并标出你关心的点:raw AST 往往只有类型/位置,增强后才更像“可读语义图”


例子 1:Python 赋值 + 二元运算 + 调用

代码

total = add(x, 2) + y

raw AST(括号式,接近 Pythonast.dump/ Tree-sitter 结构)

(Module (Assign targets=[(Name id='total' ctx=Store())] value=(BinOp left=(Call func=(Name id='add' ctx=Load()) args=[(Name id='x' ctx=Load()), (Constant value=2)] ) op=Add() right=(Name id='y' ctx=Load()) ) ) )

关键观察

  • 这里其实已经含有id='total'/'add'/'x'/'y',但很多解析器/标准化 AST可能会把这些 leaf 值抽象成Identifier类型,或只在 token 表里存(AST 节点本身只有 span)。

  • 运算符常常是一个节点Add()或 token,而不是文本"+"


例子 2:Python if + 比较 + 返回(带 else)

代码

def clamp(x, lo, hi): if x < lo: return lo elif x > hi: return hi return x

AST(更完整一点)

(Module (Assign targets=[(Name id='total' ctx=Store())] value=(BinOp left=(Call func=(Name id='add' ctx=Load()) args=[(Name id='x' ctx=Load()), (Constant value=2)] ) op=Add() right=(Name id='y' ctx=Load()) ) ) )

(Module (FunctionDef name='clamp' args=(arguments args=[x,lo,hi]) body=[ (If test=(Compare left=(Name 'x') ops=[Lt()] comparators=[(Name 'lo')]) body=[(Return (Name 'lo'))] orelse=[ (If test=(Compare left=(Name 'x') ops=[Gt()] comparators=[(Name 'hi')]) body=[(Return (Name 'hi'))] orelse=[] ) ] ), (Return (Name 'x')) ] ) )

关键观察

  • “elif” 在 AST 里常常表现成If嵌套在orelse中(这就是结构信息:树上位置决定语义)。

  • 如果你把它“纯前序 token 化”成一串If Compare Name Lt Name Return ...,模型很容易把哪个 return 属于哪个分支搞混。


例子 3:JavaScript(ESTree 风格)箭头函数 + map + 对象字面量

代码

const res = arr.map(x => ({k: x, v: x * 2}));

raw AST(接近 ESTree / Babel AST)

{ "type": "VariableDeclaration", "kind": "const", "declarations": [{ "type": "VariableDeclarator", "id": {"type": "Identifier", "name": "res"}, "init": { "type": "CallExpression", "callee": { "type": "MemberExpression", "object": {"type": "Identifier", "name": "arr"}, "property": {"type": "Identifier", "name": "map"}, "computed": false }, "arguments": [{ "type": "ArrowFunctionExpression", "params": [{"type": "Identifier", "name": "x"}], "body": { "type": "ObjectExpression", "properties": [ {"type": "Property", "key": {"type": "Identifier", "name": "k"}, "value": {"type": "Identifier", "name": "x"}}, {"type": "Property", "key": {"type": "Identifier", "name": "v"}, "value": {"type": "BinaryExpression", "operator": "*", "left": {"type": "Identifier", "name": "x"}, "right": {"type": "NumericLiteral", "value": 2}}} ] } }] } }] }

关键观察

  • JS AST 通常非常“语义化”:BinaryExpression.operator="*"MemberExpressionObjectExpression

  • 但也会很“长”:大量结构包装节点,序列化会爆 token(尤其大函数)。


例子 4:C / C++ 风格:for 循环 + 数组索引 + 累加

代码

for (int i = 0; i < n; i++) { sum += a[i]; }

AST(接近 Clang AST / Tree-sitter C 的结构)

(ForStatement init=(Declaration (InitDeclarator declarator=(Identifier "i") value=(NumberLiteral "0") ) ) condition=(BinaryExpression left=(Identifier "i") operator="<" right=(Identifier "n") ) update=(UpdateExpression operator="++" argument=(Identifier "i") ) body=(CompoundStatement (ExpressionStatement (AssignmentExpression left=(Identifier "sum") operator="+=" right=(SubscriptExpression object=(Identifier "a") index=(Identifier "i") ) ) ) ) )

关键观察

  • a[i]不是Call,而是SubscriptExpression/ArraySubscriptExpr一类节点。

  • 很多解析器会把operator当 token,而不是节点;也有的会把operator变成子节点。


例子 5:Java:try-catch + throw + 方法调用链

代码

try { return service.get(id).toString(); } catch (Exception e) { throw new RuntimeException(e); }

AST(接近 JavaParser / Eclipse JDT)

(TryStatement tryBlock=(Block (ReturnStatement expression=(MethodInvocation name="toString" scope=(MethodInvocation name="get" scope=(NameExpr "service") args=[(NameExpr "id")] ) ) ) ) catchClauses=[ (CatchClause parameter=(Parameter type="Exception" name="e") body=(Block (ThrowStatement expression=(ObjectCreationExpr type="RuntimeException" args=[(NameExpr "e")] ) ) ) ) ] )

关键观察

  • 链式调用service.get(id).toString()在 AST 里是嵌套 MethodInvocation

  • catch (Exception e)是一个带 parameter 的节点,属于TryStatement的子列表。


例子 6:未经增强的 AST(更“原始/抽象”)会长什么样?

很多论文里说的 “raw AST” 指的是:AST 节点只有类型/结构,叶子节点的具体值(标识符名、数字)不在 AST node 内,而在 tokenizer/token-table 里。那它可能更像下面这样:

代码

balance = 0

raw AST(极抽象版本:只剩类型)

(assignment_statement (left (identifier)) (right (integer)) )

这种形式当然也能序列化给 LLM:

assignment_statement left identifier right integer

但它对“总结/注释/意图理解”很不友好:模型不知道 identifier 是balance,integer 是0

而增强后的版本会更像:

(assignment_statement (left (variable:balance)) (right (integer:0)) )

信息密度立刻高很多。


你如果要“更真实”:我可以按你指定语言/解析器输出格式给

你可以告诉我你想看哪种(不用你再解释用途,我直接按常见格式给):

  1. Pythonast.dump()风格

  2. Tree-sitter S-expression 风格(很多论文用这个)

  3. JavaScript ESTree JSON(Babel/Acorn)

  4. Clang AST(C/C++)

  5. 自定义序列化:SBT / Preorder / NIT(带 children id)

你回一句:

  • “给我 3 个 Python 例子,按 tree-sitter 风格 + NIT 序列化”

  • “给我 JS 的 ESTree JSON + 对应的 NIT 序列”

我就可以把每个例子都配上树 → 序列的完整对照。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/15 18:44:44

【课程设计/毕业设计】基于springboot的小程序助农农产品销售平台基于springboot的助农农产品销售平台小程序【附源码、数据库、万字文档】

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/5/15 17:22:33

告别AI工具杂乱无章:用JVS-AI统一管理模型、知识和技能。

AI浪潮席卷各行各业的今天&#xff0c;如何高效、安全且智能地运用 AI 技术&#xff0c;是每个企业关注的焦点。对于企业而言&#xff0c;肯定想拥有一套功能强大、配置灵活的 AI 后台管理系统&#xff0c;既能轻松驾驭各类 AI 模型&#xff0c;又能巧妙管理知识、技能&#xf…

作者头像 李华
网站建设 2026/4/26 17:04:08

ionic 加载动画

ionic 加载动画 引言 在移动应用开发中,加载动画是一种常见的用户界面元素,它能够提升用户体验,同时向用户传达应用正在处理请求的信息。Ionic框架,作为一款流行的移动端应用开发框架,提供了丰富的API和组件来帮助开发者实现各种加载动画效果。本文将深入探讨Ionic框架中…

作者头像 李华
网站建设 2026/5/3 0:56:50

Unity DOTS核心概念之 Archetype(原型)

目录 前言 一、Archetype 的核心定义与本质特性 1.1 官方核心定义 1.2 三大核心本质特性 1.3 Archetype 与 ECS 核心元素的关系 二、Archetype 的内存存储机制&#xff1a;Chunk&#xff08;内存块&#xff09; 2.1 Chunk 的核心定义与特性 2.2 Chunk 的内部内存布局 …

作者头像 李华
网站建设 2026/5/15 17:28:29

2026 信创+智能双驱:四款ITSM平台深度对比,哪款更适配你的企业?

在2026年数字化转型深水区&#xff0c;企业对IT服务管理&#xff08;ITSM&#xff09;的诉求已从“流程固化”升级为“合规可控、敏捷适配、业技融合”的综合能力支撑——信创政策深化要求国产化适配&#xff0c;混合云架构普及需要跨环境协同&#xff0c;智能化技术迭代推动运…

作者头像 李华