Antlr4:如何在语法中隐藏和使用令牌

2023-12-29

我正在解析一种定义两种类型的语句的脚本语言;控制语句和非控制语句。非控制语句总是以';',而控制语句可能以以下结尾';' or EOL('\n')。语法的一部分如下所示:

script
    :   statement* EOF
    ;

statement
    :   control_statement
    |   no_control_statement
    ;

control_statement
    :   if_then_control_statement
    ;

if_then_control_statement
    :   IF expression THEN end_control_statment
        ( statement ) *
        ( ELSEIF expression THEN end_control_statment ( statement )* )*
        ( ELSE end_control_statment ( statement )* )?
        END IF end_control_statment
    ;

no_control_statement
    :   sleep_statement
    ;

sleep_statement
    :   SLEEP expression END_STATEMENT
    ;

end_control_statment
    :   END_STATEMENT
    |   EOL
    ;

END_STATEMENT
    :   ';'
    ;

ANY_SPACE
    :   ( LINE_SPACE | EOL )    ->  channel(HIDDEN)
    ;

EOL
    :   [\n\r]+
    ;

LINE_SPACE
    :   [ \t]+
    ;

在脚本语言的所有其他方面,我从不关心EOL所以我使用普通的词法分析器规则来隐藏空格。

这在所有情况下都可以正常工作,但在我需要使用的情况下EOL找到控制语句的终止点,但是使用上面的语法,所有EOL被隐藏并且不在控制语句规则中使用。

有没有办法改变我的语法,以便我可以跳过所有EOL但是终止部分控制语句所需的那些?


找到了一种方法来处理这个问题。

这个想法是将 EOL 转移到一个隐藏通道中,并将我不想在另一个隐藏通道中看到的其他内容(例如空格和注释)转移到其中。然后,当 EOL 应该出现时,我使用一些代码来回溯令牌并检查之前的令牌通道(因为它们已经被消耗)。如果我在遇到普通渠道的某些内容之前在 EOL 渠道上找到了某些内容,那么就可以了。

它看起来像这样:

更改了词法分析器规则:

@lexer::members {
    public static int EOL_CHANNEL = 1;
    public static int OTHER_CHANNEL = 2;
}

...

EOL
  : '\r'? '\n'  ->  channel(EOL_CHANNEL)
  ;

LINE_SPACE
  : [ \t]+  ->  channel(OTHER_CHANNEL)
  ;

我还将所有其他隐藏频道(评论)转移到OTHER_CHANNEL。 然后我改变了规则end_control_statment:

end_control_statment
  : END_STATEMENT
  | { isEOLPrevious() }?
  ;

并添加了

@parser::members {
  public static int EOL_CHANNEL = 1;
  public static int OTHER_CHANNEL = 2;

  boolean isEOLPrevious()
  {
        int idx = getCurrentToken().getTokenIndex();
        int ch;

        do
        {
            ch = getTokenStream().get(--idx).getChannel();
        }
        while (ch == OTHER_CHANNEL);

        // Channel 1 is only carrying EOL, no need to check token itself
        return (ch == EOL_CHANNEL);
     }
}

人们可以坚持使用普通的隐藏通道,但是在回溯时需要同时跟踪通道和令牌,因此这可能会更容易一些......

希望这可以帮助其他人处理此类问题......

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

Antlr4:如何在语法中隐藏和使用令牌 的相关文章

  • 如何为用户提供给定 boost::spirit 语法的自动完成建议?

    我正在使用 Boost Spirit 在我的 C GUI 应用程序中为非技术用户构建简单的 数据过滤器 语言 语言与纯英语非常相似 并且可以解析为 AST 我被要求使该过程尽可能对用户友好 因此我希望提供类似 CLang 的错误消息 无法识
  • 将 xml 转换为 python 字典

    我正在尝试创建一个 dict 类来处理 xml 但陷入困境 我真的没有想法了 如果有人可以指导这个主题 那就太好了 到目前为止开发的代码 class XMLResponse dict def init self xml self resul
  • 使用 string.whitespace 删除 Python 中的空格

    Python 的 string whitespace 很棒 gt gt gt string whitespace t n x0b x0c r 如何在不手动输入 t n 等正则表达式的情况下将其与字符串一起使用 例如 它应该能够转动 请不要伤
  • Java 中的递归下降解析器

    我想在序言中说这是我三年级编程语言课的家庭作业 我正在寻求一些帮助 我的作业如下 截止日期 2013年2月22日晚上11点55分提交 请将以下内容上传到CMS 1 源代码2 程序执行的屏幕截图 包括您使用的输入文件 使用您喜欢的任何编程语言
  • 自动解析 PHP,将 PHP 代码与 HTML 分离

    我正在开发一个大型 PHP 代码库 我想将 PHP 代码与 HTML 和 JavaScript 分开 我需要对 PHP 代码进行多次自动搜索和替换 对 HTML 进行不同的搜索和替换 对 JS 进行不同的自动搜索和替换 有没有一个好的解析器
  • 空白/冷融合

    停止 ColdFusion 输出空白的正确方法是什么 我知道有cfcontent and cfsetting enableCFoutputOnly 这样做的正确方法是什么 此外
  • 从 python 中的缩进文本文件创建树/深度嵌套字典

    基本上 我想迭代一个文件并将每行的内容放入一个深层嵌套的字典中 其结构由每行开头的空格数量定义 本质上 目标是采取这样的事情 a b c d e 并将其变成这样的东西 a b c d e Or this apple colours red
  • 使用 TStringList 的分隔符解析字符串,似乎也解析空格(Delphi)

    我有一个简单的字符串 由某个字符分隔 比如说逗号 我应该能够创建一个 TStringList 并将其分隔符设置为逗号 然后将 DelimitedText 设置为我想要解析的文本 并且应该自动解析它 问题是 当我查看输出时 它还包含空格作为分
  • 为什么 Visual Studio 编辑器在空白处显示点?

    我在 Visual Studio 文本编辑器中遇到了一个奇怪的错误 我所有的空格都被替换为 public class Person int age 看起来像这样 public class Person int age 我将设置重置为默认值
  • iOS 解析如何通过 URL 下载文件

    我正在将 parse 用于我的聊天应用程序 当我上传文件时 我保留该 url 并将该 url 发送给其他用户 然后其他用户可以通过该 URL 下载文件 这是我上传文件的代码 void uploadBlob NSData blob fileN
  • 在Python中连续解析文件

    我正在编写一个脚本 该脚本使用 HTTP 流量行解析文件 并取出域 目前仅将它们打印到屏幕上 我正在使用 httpry 将流量连续写入文件 这是我用来删除域名的脚本 usr bin python import re input open r
  • 用于(联合国)结构化文本文档的词法分析器/解析器[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 有很多脚本解析器和词法分析器 即结构化计算机语言 但我正在寻找一个可以将 几乎 非结构化文本文档分成更
  • 为正则表达式编写解析器

    即使经过多年的编程 我很羞愧地说我从未真正完全掌握正则表达式 一般来说 当问题需要正则表达式时 我通常可以 在一堆引用语法之后 想出一个合适的正则表达式 但我发现自己越来越频繁地使用这种技术 所以 自学并理解正则表达式properly 我决
  • 如何使用Gson仅从Json反序列化某些特定字段?

    我有以下 JSON 字符串 channel bvmt initValues data value instrumentIds TN0007250012 TN0007500010 instruments mnemonic ADWYA marc
  • Magento - 将特定父类别的子类别列为链接

    我是 php 的初学者 并且一直试图将一个父类别的子类别作为链接调用 我得到了这个 它调出了 getName 但 getUrl 根本没有返回任何 URL 输出代码只是 li a href name of sub a li
  • 在 JAVA 中使用 SAX 解析器从 XML 文件中提取文本节点

    因此 我目前正在使用 SAX 尝试从我正在处理的大量 xml 文档中提取一些信息 到目前为止 提取属性值确实很容易 但是 我不知道如何从文本节点中提取实际值 例如 在给定的 XML 文档中
  • ANTLR4 词法分析器无法解决语法顺序中的歧义

    使用 ANTLR 4 2 我尝试对此测试数据进行非常简单的解析 RRV0 ABC 使用最小语法 grammar Tiny thing RRV N HASH ID RRV RRV N 0 9 HASH ID a zA Z0 9 WS t r
  • C# 中的编译器

    我正在寻找一个可定制的解析器和 或词法分析器 它可以让我在 C 中构建自定义语法检查器 本质上 用户将输入一行代码 自定义 语法检查器将能够响应是否编写正确 That s Irony http irony codeplex com 请务必阅
  • 使用 SAX 进行 XML 解析 |如何处理特殊字符?

    我们有一个 JAVA 应用程序 可以从 SAP 系统中提取数据 解析数据并呈现给用户 使用 SAP JCo 连接器提取数据 最近我们抛出了一个异常 org xml sax SAXParseException 字符引用 是无效的 XML 字符
  • 灵气序列解析问题

    我在使用 Spirit Qi 2 4 编写解析器时遇到一些问题 我有一系列键值对以以下格式解析

随机推荐

  • 实体框架连接字符串utf8

    我想向我的实体框架数据库应用程序添加 utf8 支持 sql server 2008 r2 我想我需要将字符集添加到连接字符串中 这就是我的connectionString的工作原理 当然是匿名的
  • 如何使用log4j创建多个日志文件

    我想创建单独的日志文件 一个用于信息另一个用于调试 我正在使用下面的 log4j property 文件 请建议如何修改不同文件中的二级日志记录 Root logger option log4j rootLogger info file D
  • 我需要做什么才能在我的 xampp (Windows) 上运行 OpenSSL 扩展? :( [复制]

    这个问题在这里已经有答案了 我已经尝试过所有 但不起作用 我确实将 libeay32 dll 和 ssleay32 dll 放在 System32 windows 文件夹中 并在 php ini 上启用了 php openssl dll 扩
  • 在哪里可以找到特定于应用程序的 context.xml 文件?

    我读到了context xml file 在雄猫中 是特定于应用程序的 我已经从我的 netbeans IDE 创建了两个 Web 项目 并使用 Tomcat 作为服务器 但是我无法找到特定于应用程序的项目context xml文件 我只找
  • 在 for 循环中更改 SVG 线的 strokeDashoffset

    我正在尝试制作一条线扩展的动画 我已经在 css 中拥有它 但我需要在 javaScript 中完成它 因为这是我可以获得我需要的路径长度的唯一方法 我想我已经非常接近了 但它不起作用 有任何想法吗 以下是我的代码 正如你所看到的 我得到了
  • Python 中增加版本号

    我正在尝试对 CVS 中的文件进行版本号更新 我最初的逻辑是更新一个浮点数 1 1 gt 1 2 gt 1 3 它工作得很好 直到我到达 1 9 然后它更新到 2 0 我正在尝试使用此逻辑更新到 1 10 但是当我尝试增加 1 x 中的 x
  • 重命名类型后,我无法访问其某些方法

    为了防止项目的不同文件存在多个依赖关系 并且由于我可能会更改数据的呈现方式 我决定为绘制2D包 https github com llgcode draw2d 由于我不需要其他任何东西 我只是重命名了其中一种类型 type CanvasCo
  • 为什么我收到 apple-touch-icon-precomposed.png 错误

    我创建了一个新的 Rails3 项目 但我在服务器日志中多次看到以下日志 为什么我会收到这些请求以及如何避免这些请求 开始获取 192 168 6 2 的 apple touch icon precomposed png 2012 09 1
  • 设置数字格式以分隔千位值(例如 12000000 将变为 12 000 000)

    在lua中 我想格式化一个整数 或浮点数 以用空格 或逗号 如美国 分隔每三个小数位 因此例如数字120000010将显示为 120 000 010 或者 120 000 010 我已经发现this http lua users org w
  • RethinkDB - 更新嵌套数组

    我有一个调查表 如下所示 id Id date Date clients client id Id contacts contact id Id score Number feedback String email String 我需要更新
  • 表达式 std::string {} = "..." 是什么意思?

    在此代码中 include
  • 网格模板区域和网格模板列之间的关系

    我是编码新手 似乎没有正确理解 CSS 网格模型 在下面的代码中 网格分为 3 个网格模板列 每列 300 像素 但网格模板区域中每行有 8 个单元 例如 hd hd hd hd hd hd hd hd 而不是 3 个单元这对我来说没有意义
  • 跨域请求被阻止:同源策略不允许读取远程资源 - React js

    我在 Mac OS 设备上运行我的项目 并且想从另一台笔记本电脑进行访问 第一个设备也从服务器获取所有响应 http 192 168 1 101 3000 http 192 168 1 101 3000 但另一台笔记本电脑我收到此错误消息
  • 如何将llvm IR转换为c代码?

    有什么方法可以将 llvm IR 转换为 c 代码并保留其语义吗 例如 我们可以先将c代码编译到llvm IR 然后再将其编译回另一段c代码吗 我不希望这两个文件是相同的 但它们需要具有相同的功能 谢谢 您可以使用 C 后端 llc mar
  • 使用 MIDP 通过 http 从服务器读取 UTF8 字符串

    我想使用 java MIDP 从我控制的服务器读取 UTF 8 字符串 我的服务器正在发送 UTF 8 数据 下面的代码很接近 c StreamConnection Connector open myServer Connector REA
  • 使用样式或 Javascript 使图像变亮

    我想使用 css 或 javascript 在鼠标悬停时使网页上的图像变亮 我见过一些在样式中使用不透明度和滤镜的示例 但它们似乎对我不起作用 提前致谢 CP UPDATE 一个纯 CSS 解决方案是使用CSS 过滤器 https deve
  • 在 R 中读取二进制文件

    在以下代码中 可以导入具有这些属性的部分 LAS 文件版本 1 1 列表 项目格式 尺寸要求 X长4字节 Y长4字节 Z长4字节 强度无符号短 2 字节 返回编号 3 位 位 0 1 2 3 位 返回数 给定脉冲 3 位 位 3 4 5 3
  • 将页面映射到不同进程的地址空间

    可以使用以下命令读取和修改另一个进程地址空间中的内存ptrace 2 or process vm readv 2 process vm writev 2 但是我找不到系统调用来在另一个进程的地址空间中分配新内存 我目前能想到的唯一方法是向进
  • undefined 不是对象(评估 '_react.PropTypes.object')

    刚刚使用react native init创建了一个新项目 使用 react 16 0 0 react native 0 51 0 从 xcode 运行项目我收到以下错误 未处理的 JS 异常 模块 AppRegistry 不是已注册的可调
  • Antlr4:如何在语法中隐藏和使用令牌

    我正在解析一种定义两种类型的语句的脚本语言 控制语句和非控制语句 非控制语句总是以 而控制语句可能以以下结尾 or EOL n 语法的一部分如下所示 script statement EOF statement control statem