ANTLR 是否可以使用嵌入语法来制作语法?

2023-11-24

ANTLR:是否可以使用嵌入语法(带有自己的词法分析器)来制作语法?

例如,在我的语言中,我能够使用嵌入 SQL 语言:

var Query = [select * from table];
with Query do something ....;

可以用ANTLR吗?


是否可以使用嵌入语法(带有它自己的词法分析器)来制作语法?

如果您的意思是是否可以在单个语法中定义两种语言(使用单独的词法分析器),那么答案是:不,那是不可能的。

然而,如果问题是是否可以将两种语言解析为单个 AST,那么答案是:是的,这是可能的。

您只需要:

  • 用自己的语法定义两种语言;
  • 在主语法中创建一个词法分析器规则,捕获嵌入语言的整个输入;
  • 使用重写规则来调用自定义方法来解析外部 AST 并将其插入到主 AST 中{ ... }(参见expr主要语法中的规则(MyLanguage.g)).

我的语言.g

grammar MyLanguage;

options {
  output=AST;
  ASTLabelType=CommonTree;
}

tokens {
  ROOT;
}

@members {
  private CommonTree parseSQL(String sqlSrc) {
    try {
      MiniSQLLexer lexer = new MiniSQLLexer(new ANTLRStringStream(sqlSrc));
      MiniSQLParser parser = new MiniSQLParser(new CommonTokenStream(lexer));
      return (CommonTree)parser.parse().getTree();
    } catch(Exception e) {
      return new CommonTree(new CommonToken(-1, e.getMessage()));
    }
  }
}

parse
  :  assignment+ EOF -> ^(ROOT assignment+)
  ;

assignment
  :  Var Id '=' expr ';' -> ^('=' Id expr)
  ;

expr
  :  Num
  |  SQL -> {parseSQL($SQL.text)}
  ;

Var   : 'var';
Id    : ('a'..'z' | 'A'..'Z')+;
Num   : '0'..'9'+;
SQL   : '[' ~']'* ']';
Space : ' ' {skip();};

MiniSQL.g

grammar MiniSQL;

options {
  output=AST;
  ASTLabelType=CommonTree;
}

parse
  :  '[' statement ']' EOF -> statement
  ;

statement
  :  select
  ;

select
  :  Select '*' From ID -> ^(Select '*' From ID)
  ;

Select : 'select';
From   : 'from';
ID     : ('a'..'z' | 'A'..'Z')+;
Space  : ' ' {skip();};

主程序.java

import org.antlr.runtime.*;
import org.antlr.runtime.tree.*;
import org.antlr.stringtemplate.*;

public class Main {
  public static void main(String[] args) throws Exception {
    String src = "var Query = [select * from table]; var x = 42;";
    MyLanguageLexer lexer = new MyLanguageLexer(new ANTLRStringStream(src));
    MyLanguageParser parser = new MyLanguageParser(new CommonTokenStream(lexer));
    CommonTree tree = (CommonTree)parser.parse().getTree();
    DOTTreeGenerator gen = new DOTTreeGenerator();
    StringTemplate st = gen.toDOT(tree);
    System.out.println(st);
  }
}

运行演示

java -cp antlr-3.3.jar org.antlr.Tool MiniSQL.g 
java -cp antlr-3.3.jar org.antlr.Tool MyLanguage.g 
javac -cp antlr-3.3.jar *.java
java -cp .:antlr-3.3.jar Main

给定输入:

var Query = [select * from table]; var x = 42;

的输出Main类对应于以下 AST:

enter image description here

如果你想允许在 SQL 中使用字符串文字(其中可能包含])和评论(其中可能包含' and ]),你可以使用以下SQL主要语法中的规则:

SQL
  :  '[' ( ~(']' | '\'' | '-')
         | '-' ~'-' 
         | COMMENT 
         | STR
         )* 
     ']'
  ;

fragment STR 
  :  '\'' (~('\'' | '\r' | '\n') | '\'\'')+ '\'' 
  |  '\'\''
  ;

fragment COMMENT
  :  '--' ~('\r' | '\n')*
  ;

它将正确解析单个令牌中的以下输入:

[
  select a,b,c 
  from table 
  where a='A''B]C' 
  and b='' -- some ] comment ] here'
]

请注意,尝试为整个 SQL 方言(甚至是一个大子集)创建语法并不是一件简单的任务!您可能想要搜索现有的 SQL 解析器,或者查看 ANTLR wiki 的示例语法。

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

ANTLR 是否可以使用嵌入语法来制作语法? 的相关文章

  • 删除这种左递归方式来定义 SELECT 语句

    我正在尝试解析以下内容SELECT陈述 select 1 union all select 1 union all with cte as select 1 select 1 from tbl limit 1 union all selec
  • 有谁知道在 ANTLRWorks 中调试树语法的方法

    ANTLR 使用的推荐模式是让解析器构造一个抽象语法树 然后构建树遍历器 又称树语法 来处理它们 我试图弄清楚为什么我的树语法不起作用 并且希望使用 ANTLRWorks 的调试器 就像我将其用于解析器本身一样 解析器的输入是 源代码 但树
  • Rust 的词法语法是规则的、上下文无关的还是上下文相关的?

    大多数编程语言的词法语法都相当缺乏表达力 无法快速对其进行词法分析 我不确定 Rust 的词法语法属于什么类别 大多数看起来很正常 可能除了原始字符串文字 https doc rust lang org reference tokens h
  • ANTLRWorks 1.4.3 无法正确读取扩展 ASCII 字符

    我正在开发一个相当标准的编译器项目 我选择 ANTLR 作为解析器生成器 在将现有语法从 v2 更新到 v3 时 我注意到 ANTLRWorks ANTLR 的官方 IDE 无法正确显示文件中的任何扩展 ASCII 字符 即使使用 Note
  • C# ANTLR 语法?

    我正在寻找交钥匙ANTLR http www antlr org C 语法 生成可用的抽象语法树 AST 并且与后端语言无关或以 C C C 或 D 为目标 它不需要支持错误报告 附 我不愿意做任何修复 因为替代方案并不难 这可能太晚了 但
  • Antlr3:无法匹配词法分析器规则中使用的解析器规则中的标记

    我在 Antlr3 中的词法分析器规则为 HYPHEN TOKEN HYPHEN CHARS CHARS a z 解析器规则如下 exp CHARS some complex expression parser rule exp HYPHE
  • Antlr4中有哪些加速解析的方法?

    我对Antlr4的性能有些怀疑 我目前正在使用 Python 和 Antlr4 与 Java 相比 它非常慢 使用 Antlr4 IntelliJ 插件验证 由于我需要使用更大的代码进行解析 因此我计划切换到 Antlr 最快的语言 例如
  • 解析树和语法信息

    有谁知道在哪里可以找到好的在线资源以及如何制作语法和解析树的示例 最好是介绍材料 信息是 n00b 友好的 我自己在 Google 上没有找到任何好的信息 Edit 我正在考虑理论 而不是特定的解析器软件 网上没有 不过也许你应该看看编译器
  • ANTLR 实现类似Python的缩进相关语法的最简单方法是什么?

    我正在尝试实现类似Python的缩进相关语法 来源示例 ABC QWE CDE EFG EFG CDE ABC QWE ZXC 正如我所看到的 我需要的是实现两个标记 INDENT 和 DEDENT 所以我可以编写如下内容 grammar
  • Perl 6 语法与我认为的不匹配

    我正在做代码出现第 9 天 http adventofcode com 2017 day 9 您坐了一会儿并记录了流的一部分 您的谜题输入 这些字符代表组 开头的序列 并结束于 在一个组内 有零个或多个其他东西 用逗号分隔 要么是另一个组
  • 使用 ANTLR 解析时忽略输入的某些部分

    我正在尝试通过 ANTLR ANTLRWorks 3 5 2 解析语言 目标是输入完整的输入 但 Antlr 给出语法中定义部分的解析树并忽略其余输入 例如这是我的语法 grammar asap project begin PROJECT
  • 自动解析 PHP,将 PHP 代码与 HTML 分离

    我正在开发一个大型 PHP 代码库 我想将 PHP 代码与 HTML 和 JavaScript 分开 我需要对 PHP 代码进行多次自动搜索和替换 对 HTML 进行不同的搜索和替换 对 JS 进行不同的自动搜索和替换 有没有一个好的解析器
  • 是否有一个实用程序可以在给定 ANTLR 语法的情况下生成匹配的字符串?

    我有一个 ANTLR 语法 我想模 糊我的解析器 您是否正在寻找 CFG 语法的生成 IE 语法接受的字符串的生成 这可能是检查语法正确性的好主意 但请记住 可接受的字符串集很可能是无限的 任何真正严重的错误应该已经在语法规范中显而易见 并
  • 有没有使用 ANTLR 或类似语言实现的简单语言?

    我正在尝试构建一种简单的解释语言以用于学习目的 我读过无数关于 ANTLR 和 JavaCC 的理论和教程 但我不知道如何真正让它做一些有用的事情 我通过 把东西拆开然后重新组合起来 来学得最好 那么 是否有任何在 ANTLR 或类似工具的
  • 使用 ANTLR 为 java 源代码生成抽象语法树

    如何使用 ANTLR 从 java src 代码生成 AST 有什么帮助吗 好的 步骤如下 前往ANTLR站点 http www antlr org 并下载最新版本 下载Java g和JavaTreeParser g文件来自here htt
  • ANTLR 获取并拆分词法分析器内容

    首先 对我的英语感到抱歉 我还在学习 我为我的框架编写 Python 模块 用于解析 CSS 文件 我尝试了 regex ply python 词法分析器和解析器 但我发现自己在 ANTLR 中 第一次尝试 我需要解析 CSS 文件中的注释
  • Xtext和ANTLR之间有什么关系?

    我听说Xtext最终使用ANTLR 但他们的语法规范文件的格式有些不同 那么两者之间是什么关系呢 Xtext 依赖于 Antlr 解析器生成器来解析输入文件 除此之外 该框架还提供了许多附加值 例如强类型 AST 链接抽象和静态分析以及 E
  • ANTLR4 在导入时找不到语法

    我正在尝试将 ANTLR4 语法拆分为多个文件 以便我可以更轻松地测试它们 我在 java 项目中使用 gradle 作为构建工具 两种语法都单独正确编译 但是当我将导入添加到我的主语法中时 我收到下一个编译错误 错误 110 kaneko
  • ANTLR 和 Eclipse(或任何像样的 IDE)

    我已经使用 ANTLRv3IDE 插件在 Eclipse 中使用 ANTLR 一段时间了 虽然它并不完美 而且有点过时 但它的工作相当不错 现在 我希望将我正在创建的另一个 DSL 切换到 ANTLRv4 然而 Eclipse 的支持似乎非
  • Antlr 解析器运算符优先级

    考虑以下语法 我对运算符优先级有疑问 例如 res 2 a b有一个类似的解析树res 2 a b 我知道问题出在哪里 但我没有想到没有相互左递归的 漂亮 解决方案 你能帮我一点忙吗 该语法与自定义访问者一起使用 grammar Math

随机推荐