按语法解析为 AST(或 .y+.lang => xml)的工具

2023-12-23

给定一个词法分析器定义文件、一个语法文件(例如 postgresql.y,.lflex 和 bison 程序来自它的源树),以及由这些词法分析器和解析器定义的文件(例如,SQL 查询)以某种标准形式(例如,XML 的 JSON)获取 AST。

该工具最重要的方面是 - 输入格式的灵活性。在我的示例中,我可以在 ANTLR 中重新创建 postgres SQL 语法 - 但我不想这样做。我宁愿只使用 postgres 使用的任何东西。所以尽管.y文件包含的不仅仅是解析规则 - 我正在寻找的工具将能够通过较小的修改来理解它们。

有没有通用工具可以做到这一点?

这是我想象的工具的命令行会话ly2xml:

$ git clone git://postgres-git-url pg
$ find pg -iname *.[yl] -exec cp '{}' ~/ \;
$ echo 'SELECT * FROM (SELECT 1)'|ly2xml -parser=*.y -lexer=*.l - -O-
<SELECT>
  <ARGS>*</ARGS>
  <FROM>
    <SELECT><ARGS>1</ARGS></SELECT>
  </FROM>
</SELECT>

(注意-意味着它从标准输入读取,并且-O-意味着它写入标准输出)。


不错的想法。您假设以下一项或多项:

 a) that each tool that has a grammar, uses a canonical parsing engine type (e.g., everybody uses bison)
 b) that there is some parsing tool that understands the zillion grammar specification schemes that exist
 c) that whatever the parser is, it will parse language fragments (perhaps well formed).

a) 显然是错误的。我从来没见过b)。实际上没有一个解析引擎会执行 c);他们只能解析“完整程序”。

恕我直言,您唯一的希望是使用具有大量经过良好测试的语言定义的解析器生成器。

ANTLR http://www.antlr.org可以说是一个;它当然有一长串贡献的语言定义。而且它们都可以在一个地方找到。但据我所知,不做语言片段。怀疑它是否具有所有解析树的 XML 导出。

Bison http://www.gnu.org/software/bison可以说是一个;有很多很多的语言处理器是使用 Bison 构建的。但定义分散各处,收集起来非常困难。也不做语言片段。很确定它没有 XML 导出功能。

Our DMS 软件再造工具包 http://www.semanticdesigns.com/Products/DMS/DMSToolkit.html可以说是一个。有很多语言定义。它们都收集在一个地方(我们公司)。它确实为每个解析生成 AST,并且具有内置的 XML 导出。 DMS 还可以解析任何它所知道的任何语言的非终结符语言。

给定 DMS .lex、.atg(“属性语法”)和兼容的源文件,DMS 可以很好地模拟您的示例。

接下来是 DMS 词法分析器/解析器的构建和运行,并带有 XML 导出,用于在以下位置找到的代数语法:作为 DMS 域的代数 http://www.semanticdesigns.com/Products/DMS/SimpleDMSDomainExample.html (the ++XML该示例的中间部分是被告知导出 XML 的解析步骤):

C:\DMS\Domains\Algebra\Tools\Parser\Source>make
perl /cygdrive/c/DMS/Executables/MakeDMSTool Algebra -lexer
MakeDMSTool: Selected domain "Algebra".
LexerGenerator V2.1a
Copyright (c) 1999-2010 Semantic Designs, Inc.; All Rights Reserved
Parsing lexical specification ...
Processing mode Algebra ...
Exiting with final status 0
perl /cygdrive/c/DMS/Executables/MakeDMSTool Algebra -tool %Temporaries
MakeDMSTool: Selected domain "Algebra".
Using attribute grammar in "/cygdrive/c/DMS/Domains/Algebra/Tools/Parser/Source/Syntax/Algebra.atg"
AttributeEvaluatorGenerator V3.0
Copyright (c) 1999-2010 Semantic Designs, Inc.; All Rights Reserved
Parsing attribute grammar ...
Generating attribute evaluator(s) ...
Exiting with final status 0

rm -rf /cygdrive/c/DMS/Domains/Algebra/Tools/%Temporaries
perl /cygdrive/c/DMS/Executables/MakeDMSTool Algebra -prettyprinter
MakeDMSTool: Selected domain "Algebra".
PrettyPrinterGenerator V2.0
Copyright (c) 1999-2010 Semantic Designs, Inc.; All Rights Reserved

Parsing pretty printer specification ...
Generating pretty printer ...
Exiting with final status 0

AttributeEvaluatorGenerator V3.0
Copyright (c) 1999-2010 Semantic Designs, Inc.; All Rights Reserved
Parsing attribute grammar ...
Generating attribute evaluator(s) ...
......................

Exiting with final status 0
cd /cygdrive/c/DMS/Domains/Algebra/Tools/Parser/Source/\%Generated; \
    perl /cygdrive/c/DMS/Executables/MakeDMSTool Algebra -weave-preserve-productions %PreserveProductions.*.par
MakeDMSTool: Selected domain "Algebra".
perl /cygdrive/c/DMS/Executables/MakeDMSTool Algebra -parser
MakeDMSTool: Selected domain "Algebra".
export PARLANSEINCLUDEDIRECTORIES=`perl -e '($_ = $ARGV[0].";/cygdrive/c/DMS/Domains/PARLANSE/Library/Arrays;/cygdrive/c/DMS/Domains
/PARLANSE/Library/Bags;/cygdrive/c/DMS/Domains/PARLANSE/Library/HashTables;/cygdrive/c/DMS/Domains/PARLANSE/Library/Pipes;/cygdrive/
c/DMS/Domains/PARLANSE/Library/Sequences;/cygdrive/c/DMS/Domains/PARLANSE/Library/Sets;/cygdrive/c/DMS/Domains/PARLANSE/Library/Stac
ks;/cygdrive/c/DMS/Domains/PARLANSE/Library/Utilities;/cygdrive/c/DMS/Domains/PARLANSE/Library/Algorithms/Source;/cygdrive/c/DMS/Dom
ains/PARLANSE/Library/Booleans/Source;/cygdrive/c/DMS/Domains/PARLANSE/Library/Characters/Source;/cygdrive/c/DMS/Domains/PARLANSE/Li
brary/Graphics/Source;/cygdrive/c/DMS/Domains/PARLANSE/Library/HashTrees/Source;/cygdrive/c/DMS/Domains/PARLANSE/Library/Numbers/Sou
rce;/cygdrive/c/DMS/Domains/PARLANSE/Library/References/Source;/cygdrive/c/DMS/Domains/PARLANSE/Library/SQL/Source;/cygdrive/c/DMS/D
omains/PARLANSE/Library/Streams/Source;/cygdrive/c/DMS/Domains/PARLANSE/Library/SuffixTrees/Source;/cygdrive/c/DMS/Domains/PARLANSE/
Library/System/Source;/cygdrive/c/DMS/Domains/PARLANSE/Library/Search/Source;/cygdrive/c/DMS/Domains/PARLANSE/Library/TestSupport/So
urce") =~ s!//(.)/!$1:/!g; $_ =~ s!/cygdrive/(.)/!$1:/!g; print $_' "/cygdrive/c/DMS/Domains/Algebra/Tools/Parser/Source;/cygdrive/c
/DMS/Domains/Algebra/Tools/Parser/Source/Components;/cygdrive/c/DMS/Domains/Algebra/Tools/Parser/Source/%Generated;/cygdrive/c/DMS/D
omains/DMSStringGrammar/Tools/DomainParser/Source;/cygdrive/c/DMS/Domains/Algebra/Tools/Lexer/Source;/cygdrive/c/DMS/Domains/Algebra
/Tools/Lexer/Source/%Generated;/cygdrive/c/DMS/Domains/DMSLexical/Tools/DomainLexer/Source;/cygdrive/c/DMS/Infrastructure/HyperGraph
/Source;/cygdrive/c/DMS/Domains"`; \
    cd `echo /cygdrive/c/DMS/Domains/Algebra/Tools/Parser/Source`; \
    nice /cygdrive/c/DMS/Domains/PARLANSE/Tools/Compiler/p0c.exe  DomainParser.par
PARLANSE0 Compiler V19.16.40
Semantic Designs, Inc. *** Confidential Information
128/485/133408 smallest/average/largest activation record/grain stack space required.
Largest stack space required by function at Line    1533
 in file FFIModule.par
89 grains.
3775 functions/procedures.
223447 lines of source code read.
7160772 bytes of object code.
No errors detected.
mv -f /cygdrive/c/DMS/Domains/Algebra/Tools/Parser/Source/DomainParser.P0B /cygdrive/c/DMS/Domains/Algebra/Tools/Parser/DomainParser
.P0B

C:\DMS\Domains\Algebra\Tools\Parser\Source>run ../DomainParser ++XML C:\DMS\Domains\Algebra\Tools\Lexer\TestCase\algebraformula.txt
Domain Parser for Algebra 2.3.3
Copyright (C) Semantic Designs 1996-2010; All Rights Reserved
31 tree nodes in tree.
<DMSForest>
 <tree node="formula" type="1" domain="1" id="10qx0" parents="0" line="1" column="1" file="1">
  <tree node="product" type="4" domain="1" id="10qwx" line="1" column="1" file="1">
   <tree node="term" type="10" domain="1" id="10qwy" line="1" column="1" file="1">
<tree node="'D'" type="19" domain="1" id="10qw5" literal="0" line="1" column="1" file="1"/>
<tree node="'['" type="20" domain="1" id="10qw6" literal="0" line="1" column="2" file="1"/>
<tree node="formula" type="1" domain="1" id="10qwt" line="1" column="4" file="1">
 <tree node="product" type="4" domain="1" id="10qws" line="1" column="4" file="1">
  <tree node="term" type="9" domain="1" id="10qwr" line="1" column="4" file="1">
   <tree node="'('" type="17" domain="1" id="10qw7" literal="0" line="1" column="4" file="1"/>
   <tree node="formula" type="3" domain="1" id="10qwp" line="1" column="5" file="1">
    <tree node="formula" type="2" domain="1" id="10qwk" line="1" column="5" file="1">
     <tree node="formula" type="1" domain="1" id="10qwf" line="1" column="5" file="1">
      <tree node="product" type="5" domain="1" id="10qwe" line="1" column="5" file="1">
       <tree node="product" type="4" domain="1" id="10qwa" line="1" column="5" file="1">
    <tree node="term" type="7" domain="1" id="10qw9" line="1" column="5" file="1">
     <tree node="VARIABLE" type="15" domain="1" id="10qw8" line="1" column="5" file="1">
      <literal>x</literal>
     </tree>
    </tree>
       </tree>
       <tree node="'*'" type="13" domain="1" id="10qwb" literal="0" line="1" column="7" file="1"/>
       <tree node="term" type="8" domain="1" id="10qwd" line="1" column="8" file="1">
    <tree node="NUMBER" type="16" domain="1" id="10qwc" literal="23" line="1" column="8" file="1"/>
       </tree>
      </tree>
     </tree>
     <tree node="'+'" type="11" domain="1" id="10qwg" literal="0" line="1" column="10" file="1"/>
     <tree node="product" type="4" domain="1" id="10qwj" line="1" column="12" file="1">
      <tree node="term" type="7" domain="1" id="10qwi" line="1" column="12" file="1">
       <tree node="VARIABLE" type="15" domain="1" id="10qwh" line="1" column="12" file="1">
    <literal>y</literal>
       </tree>
      </tree>
     </tree>
    </tree>
    <tree node="'-'" type="12" domain="1" id="10qwl" literal="0" line="1" column="13" file="1"/>
    <tree node="product" type="4" domain="1" id="10qwo" line="1" column="14" file="1">
     <tree node="term" type="7" domain="1" id="10qwn" line="1" column="14" file="1">
      <tree node="VARIABLE" type="15" domain="1" id="10qwm" line="1" column="14" file="1">
       <literal>z</literal>
      </tree>
     </tree>
    </tree>
   </tree>
   <tree node="')'" type="18" domain="1" id="10qwq" literal="0" line="1" column="15" file="1"/>
  </tree>
 </tree>
</tree>
<tree node="','" type="21" domain="1" id="10qwu" literal="0" line="1" column="16" file="1"/>
<tree node="VARIABLE" type="15" domain="1" id="10qwv" line="1" column="18" file="1">
 <literal>x</literal>
</tree>
<tree node="']'" type="22" domain="1" id="10qww" literal="0" line="1" column="19" file="1"/>
   </tree>
  </tree>
 </tree>
 <FileIndex>
  <File index="1">C:/DMS/Domains/Algebra/Tools/Lexer/TestCase/algebraformula.txt</File>
 </FileIndex>
 <DomainIndex>
  <Domain index="1">Algebra</Domain>
 </DomainIndex>
</DMSForest>
Exiting with final status 0

C:\DMS\Domains\Algebra\Tools\Parser\Source>

If you really如果想要一个能够理解许多语法符号的引擎,那么使用 DMS 构建这样的引擎可能是最简单的。只需将每个语法形式(例如 ANTLR 或 bison)定义为 DMS 的 DSL,使用 DMS 解析特定语法形式实例(例如 ANLTR bnf 实例),应用 DMS 重写规则将其转换为 DMS 语法,然后构建 DMS 解析器。 (您也必须对词法分析器执行相同的操作。)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

按语法解析为 AST(或 .y+.lang => xml)的工具 的相关文章

  • serde_json::from_str 错误,其中字符串来自文件

    extern crate serde json use serde json Value use std fs File use std io prelude fn main let filepath map test anhui txt
  • 学习树顶

    我正在尝试自学 Ruby 的 Treetop 语法生成器 我发现 对于 最好的 文档来说 不仅文档非常稀疏 而且它的工作方式似乎并不像我希望的那样直观 从高层次上来说 我真的很喜欢比现场文档或视频更好的教程 如果有的话 在较低的层面上 这是
  • 解析整数集的字符串并列出间隔

    I have 2 5 7 9 12 string 我想从中获取 2 5 7 8 9 12 列表 python中有没有内置的函数 Thanks UPD 我想 直接的答案是No 不管怎样 谢谢你的 片段 使用一个 建议者斯文 马尔纳克 s 2
  • 如何使用 alex/haskell 执行 python 风格的缩进/缩进标记?

    我正在用 Haskell 为 Alex 中的一种小语言编写一个词法分析器 该语言被指定为具有 python 式的显着缩进 只要缩进级别发生变化 就会发出 INDENT 标记或 DEDENT 标记 在像 C 这样的传统命令式语言中 您将在词法
  • 如何在 PHP 中实现前向索引?

    我希望在 PHP 中实现一个简单的前向索引器 是的 我确实知道 PHP 并不是完成这项任务的最佳工具 但无论如何我还是想这样做 其背后的理由很简单 我想要一个 并且是 PHP 版本 让我们做一些基本假设 整个互联网包括 大约五千个 HTML
  • 从电话号码确定国际电话代码的算法

    我可以使用 iOS 上的地址簿框架从设备中检索联系人的电话号码 如何区分或识别哪个是国家 地区代码 哪个是实际电话号码 是否可以 国家 地区代码是一个相当混乱的主题 但足够标准 通过一些程序员维护就可以解决它 您可以通过其初始子序列来识别国
  • 如何从 Java 生产代码中删除调试语句

    编译器是否可以从生产代码中删除用于调试目的 例如日志记录 的语句 调试语句需要以某种方式进行标记 可能使用注释 设置属性 debug true 并在每个调试语句中检查它很容易 但这会降低性能 如果编译器能够简单地使调试语句消失 那就太好了
  • 什么是应用程序二进制接口 (ABI)?

    我从来没有清楚地理解什么是 ABI 请不要向我指出维基百科文章 如果我能理解的话 我就不会在这里发这么长的帖子了 这是我对不同接口的看法 电视遥控器是用户和电视之间的接口 它是一个现有的实体 但本身没有用 不提供任何功能 遥控器上每个按钮的
  • C# 编译器编译 .txt .obj .java 文件

    using System class Program public static void Main Console WriteLine Hello World Console ReadLine 我将文件另存为1 java 2 obj an
  • Java代码编译器优化[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我想知道 给定一个 java 代码 我如何才能看到 Java 编译器如何优化它 有没有 JDK 工具可以实现这一点 试图用谷歌搜索 但没有
  • 是否有更快的方法来检查 LINQ to XML 中的 XML 元素并解析 bool?

    仅供参考 这与我的上一个问题非常相似 是否有更快的方法来检查 LINQ to XML 中的 XML 元素 https stackoverflow com questions 2065665 is there a faster way to
  • Scala 组合器解析器 - 区分数字字符串和变量字符串

    我正在做 Cay Horstmann 的组合器解析器练习 我想知道区分代表数字的字符串和代表匹配语句中变量的字符串的最佳方法 def factor Parser ExprTree wholeNumber expr ident case a
  • 如何为 iPhone 构建静态库?

    我想我已经到处寻找问题的答案 但没有运气 我正在尝试创建一个简单的静态库来在 iPhone 设备上运行 但我总是以 XCode 结束 说 文件不属于必需的架构 并且我已经尝试了我发现的每个构建标志 但没有任何运气 我已经让它在模拟器上工作了
  • ANTLR4 在导入时找不到语法

    我正在尝试将 ANTLR4 语法拆分为多个文件 以便我可以更轻松地测试它们 我在 java 项目中使用 gradle 作为构建工具 两种语法都单独正确编译 但是当我将导入添加到我的主语法中时 我收到下一个编译错误 错误 110 kaneko
  • 是否可以使用 fparsec 解析“越位”(基于缩进)语言?

    我希望将 FParsec 用于基于缩进的类似 python 的语言 我知道这必须在词法分析阶段完成 但 FParsec 没有词法分析阶段 是否可以使用 FParsec 或者 词法分析后如何提供它 P D 我是 F 新手 但在其他语言方面经验
  • 寻找引文解析器

    我需要一个解析器来扫描学术文本 提取引文 并将这些引文解析为其组成部分 作者 标题 出版日期等 我尝试过 Paracite 但它速度非常慢 而且不能产生高质量的结果 任何语言都可以 但首选 Java 看一眼ParsCit http aye
  • Bison:奇怪的转变-减少冲突

    我尝试在自定义语法中实现函数调用 加上类似的数组访问运算符 expression OTHER EXPRESSION RULES expression PARENTHESIS OPEN expressions PARENTHESIS CLOS
  • String.Format 小数,带有千位分隔符和强制小数位

    我想String Format小数 使其同时具有千位分隔符和强制小数位 3 例如 Input 123456 12 78545 8 Output 123 456 120 78 545 800 我努力了 String Format 0 0 0
  • 在 Delphi 中使用 XML(将特定数据返回到变量)

    过去几天我一直在尝试使用 Delphi 2010 和 MSXML 我是一个极端的新手 需要一点指导 var MemoryStream TMemoryStream XMLPath String sName String XMLDoc vari
  • 如何使用 ICU 解析汉字数字字符?

    我正在编写一个使用 ICU 来解析由汉字数字字符组成的 Unicode 字符串的函数 并希望返回该字符串的整数值 五 gt 5 三十一 gt 31 五千九百七十二 gt 5972 我将区域设置设置为 Locale getJapan 并使用

随机推荐

  • Python 中的 MySQL 连接器不允许 LOAD DATA INFILE 语法

    我正在尝试将文本文件发送到 MySQL 数据库 我正在尝试使用 python 3 2 中的 mysql 连接器来执行此操作 问题与 LOAD DATA INFILE 语法有关 你可以在上面找到我的代码 我的第一个问题是有没有办法解决这个问题
  • Android:使用 Intent setResults 来回传递数据

    我正在为 Android 创建一个基于 GPS 的应用程序 有 2 个活动 Main 和 LocNames Main 显示我的地图 LocNames 是获取用户想要的源和目的地 我想在用户从菜单中选择 LocNames 时启动 LocNam
  • Tensorflow 2.0 和 Java API

    注意 我已经解决了我的问题并将代码发布在底部 我正在使用 TensorFlow 后端处理必须在 Java 中进行 我从 中取出了其中一个模型https developers google com machine learning crash
  • 如何为异步方法编写单元测试用例?

    我想通过模拟依赖项来编写单元测试用例 整体流程如下 我们有一个WorklistLoader它有一个异步方法LoadWorklistItemsAsync 为了完成这个任务WorklistLoader依赖于下层 API 我想模拟 QueryMa
  • 在不处于编辑模式时对 tableView 中的行重新排序[重复]

    这个问题在这里已经有答案了 在我的应用程序中 我已经实现了重新排序行的选项 但我使用默认的编辑按钮来显示删除按钮和三行图标来移动行 但我见过一个iOS应用程序允许用户直接移动行 而不需要进入编辑模式 我将不胜感激任何建议来实现这种方式 以允
  • linux 补丁忽略行号

    我有一个产品 例如版本 1 并且对其进行了一些自定义更改 例如版本 1 x 我正在对这些版本运行差异并创建补丁文件 现在该产品有更高版本 例如版本 2 我希望将从版本 1 和版本 1 x 创建的补丁应用于版本 2 这里的困难在于行号不会保持
  • Java 线程:解释正在运行的 JVM 的线程状态

    Java 线程始终处于以下十种状态之一 NEW Just starting up i e in process of being initialized NEW TRANS Corresponding transition state no
  • 从 mp3/ogg 中剪切精确的时间范围

    我在 CDN 上有一堆音频文件 这些是并行的 mp3 和 ogg vorbises 这些文件每个都值得播放大约一小时 我需要从这些文件中提取任意部分 我得到一个文件名 我可以选择是否使用 mp3 或 ogg 版本 和两个时间戳 并且我需要恰
  • 计算iTextSharp PDF文档的高度?

    使用iTextSharp时如何计算PDF文档的高度 我正在使用 iTextSharp 使用绝对位置在 PDF 文档上定位各种图像 不过我注意到了SetAbsolutePosition 定位Y参数来自底部 所以我需要计算高度才能执行以下操作
  • MongoDB MapReduce是否锁定数据库

    MongoDB MapReduce 作业是否会锁定数据库 我正在开发一个多用户 MongoDB Web 应用程序 并且担心多用户冲突和性能 有人能给我一些至理名言吗 简单的回答 有时 这在很大程度上取决于您如何使用map reduce 但根
  • Electron:删除 beforeunload 事件监听器

    我有一个电子应用程序 用于显示我无法控制的网页 该应用程序的使用是为了每隔几秒钟就可以显示一个不同的页面 显示的页面之一附加了一个 beforeunload 监听器 如下所示 window addEventListener beforeun
  • 如何获取winexec或shellexecute中执行的Handle?

    我用来创建像 winexec Hand 这样的自定义函数 它将返回执行的应用程序的句柄 我确实使用了 findwindow 但如果它更改窗口标题就会出现问题 没有一种通用方法可以获取应用程序的 该 窗口句柄 因为不能保证任何程序都有一个窗口
  • 在 v23 上找不到符号 Manifest.permission.WRITE_EXTERNAL_STORAGE

    我使用以下 build gradle 文件编译代码 android compileSdkVersion 23 buildToolsVersion 23 0 1 defaultConfig applicationId com example
  • 作曲家权限被拒绝(公钥)

    我在 BitBucket 上有一个私人存储库 我尝试使用composer install在本地主机上安装 这是我的composer json文件 repositories type git url email protected cdn c
  • 初始化函数的目的

    我经常看到构造函数只调用 init 函数 如果您可以将 init 函数的内容放入构造函数中 为什么还要使用 init 函数呢 每个实例仅调用对象的构造函数一次 而 init 函数可能会调用多次 考虑以下代码 public class Foo
  • 使用 JLayeredPane 将多个 JPanel 添加到一个 JPanel 中

    我正在尝试将多个面板添加到另一个面板 我希望它们位于彼此之上 因此我使用 JLayeredPane 我为每个按钮添加了一个按钮 工作时应该出现两个按钮 import java awt Color import javax swing JBu
  • 如果UDF公式失败,Excel VBA保留原始值

    在各个单元格中 我有一个引用 UDF 的指定公式 getValueFromWorkbook OtherWorkbook 10 The getValueFromWorkbookUDF 大致做了类似的事情 Function getValueFr
  • 子域重定向到另一台服务器

    我有一个通过共享托管计划托管的网站 我的域名是在GoDaddy注册的 域名服务器是我的共享主机的域名服务器 到目前为止 一切正常 但我试图弄清楚如何添加子域并将其指向其他地方 我想将 sub mydomain com 指向其他一些 IP 在
  • 与 .pub 文件的 SSH 连接

    我从客户那里得到了 id rsa pub 我被告知要连接到它 我尝试添加密钥ssh copy id email protected cdn cgi l email protection 但它给出了错误 Permission denied p
  • 按语法解析为 AST(或 .y+.lang => xml)的工具

    给定一个词法分析器定义文件 一个语法文件 例如 postgresql y lflex 和 bison 程序来自它的源树 以及由这些词法分析器和解析器定义的文件 例如 SQL 查询 以某种标准形式 例如 XML 的 JSON 获取 AST 该