在 ANTLR4 中如何检查行的第一个字符是否为“*”?

2024-05-09

我正在尝试为一种相对简单但特殊的语言编写一个解析器。

简单地说,规则之一是注释行用星号表示only如果该星号是该行的第一个字符。我如何在 ANTLR4 中正式化这样的规则?我考虑过使用:

START_LINE_COMMENT: '\n*' .*? '\n' -> skip; 

但我确信这不适用于连续多于一行的注释,因为最后的换行符将作为START_LINE_COMMENT令牌,这意味着任何后续注释行都将缺少所需的初始换行符,这将不起作用。有没有办法我可以检查该行是否以'*'无需消耗之前的'\n'?


匹配注释行并不容易。当我每年写一篇语法时,我必须抓住权威的 ANTLR 参考 https://pragprog.com/book/tpantlr2/the-definitive-antlr-4-reference让我的大脑清醒一下。尝试这个 :

grammar Question;

/* Comment line having an * in column 1. */

question
    :   line+
    ;

line
//    :   ( ID | INT )+
    :   ( ID | INT | MULT )+
    ;

LINE_COMMENT
    :   '*' {getCharPositionInLine() == 1}? ~[\r\n]* -> channel(HIDDEN) ;
ID  :   [a-zA-Z]+ ;
INT :   [0-9]+ ;
//WS  :   [ \t\r\n]+ -> channel(HIDDEN) ;
WS  :   [ \t\r\n]+ -> skip ;
MULT : '*' ;

编译并执行:

$ echo $CLASSPATH
.:/usr/local/lib/antlr-4.6-complete.jar:
$ alias
alias a4='java -jar /usr/local/lib/antlr-4.6-complete.jar'
alias grun='java org.antlr.v4.gui.TestRig'
$ a4 Question.g4 
$ javac Q*.java
$ grun Question question -tokens data.txt 
[@0,0:3='line',<ID>,1:0]
[@1,5:5='1',<INT>,1:5]
[@2,9:12='line',<ID>,2:2]
[@3,14:14='2',<INT>,2:7]
[@4,16:26='* comment 1',<LINE_COMMENT>,channel=1,3:0]
[@5,32:35='line',<ID>,4:4]
[@6,37:37='4',<INT>,4:9]
[@7,39:48='*comment 2',<LINE_COMMENT>,channel=1,5:0]
[@8,51:78='* comment 3 after empty line',<LINE_COMMENT>,channel=1,7:0]
[@9,81:81='*',<'*'>,8:1]
[@10,83:85='not',<ID>,8:3]
[@11,87:87='a',<ID>,8:7]
[@12,89:95='comment',<ID>,8:9]
[@13,97:100='line',<ID>,9:0]
[@14,102:102='9',<INT>,9:5]
[@15,107:107='*',<'*'>,9:10]
[@16,109:110='no',<ID>,9:12]
[@17,112:118='comment',<ID>,9:15]
[@18,120:119='<EOF>',<EOF>,10:0]

具有以下 data.text 文件:

line 1
        line 2
* comment 1
    line 4
*comment 2

* comment 3 after empty line
 * not a comment
line 9    * no comment

请注意,如果没有MULT令牌或'*'在解析器规则中的某处,星号未在标记中列出,但解析器抱怨:

line 8:1 token recognition error at: '*'

如果显示解析树

$ grun Question question -gui data.txt

您会看到整个文件被一行规则吸收。如果您需要识别行,请更改行和空白规则,如下所示:

line
    :   ( ID | INT | MULT )+ NL
    |   NL
    ;

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

在 ANTLR4 中如何检查行的第一个字符是否为“*”? 的相关文章

随机推荐

  • Rails - 使链接与 ajax 一起工作

    我有一个链接 应该使用 ajax 加载它旁边的部分内容 而无需重新加载页面 链接在这里 这是链接应该转到的控制器 class ProfilesController lt ApplicationController def profile f
  • 反转二进制网络

    如何反转二元方程 以便找到哪些输入将产生给定的输出 Example Inputs i0 through i8 Outputs o0 through o8 Operators XOR AND 二元方程 1 i0 1 i1 0 i2 1 i3
  • 用于真实 Web 项目的 Scala-JS [已关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 有人用过吗Scala JS在真实的网络项目中 但不仅仅适用于普通的JavaScript在隔离环境中替换 我想尽可能多地使用 Scala 我希望可
  • JavaScript - 这个这个

    String prototype foo String prototype foo bar function How can you reference the grandparent string console log this par
  • 如何使用 terraform 创建 azure 应用程序注册和客户端密钥

    我正在尝试为 Azure 应用程序注册和客户端密钥创建 Terraform 代码 对订阅具有读取访问权限的服务主体 基本上 我正在尝试将 Azuresafe 与 Terraform 集成 并尝试确定如何逐步配置 https docs saf
  • 为什么这个 CSS nowrap 不起作用?

    我试图阻止 bar top container div 包裹它的内容 无论页面有多宽 即两个选择应该始终出现在同一行 但是当页面宽度太小而无法容纳它们时 这不起作用一方面 我该如何解决这个问题 Styles bar top containe
  • 不兼容的类型 - 是因为数组已经是指针吗?

    在下面的代码中 我创建一个基于书籍结构的对象 并让它保存多个 书籍 我设置的是一个数组 即定义 启动的对象 然而 每当我去测试我对指针的了解 实践有帮助 并尝试创建一个指向创建的对象的指针时 它都会给我错误 C Users Justin D
  • 如何得到将外力映射到广义力的矩阵?

    给定一个多体植物 我需要找到将外力 lambda 转换为广义力的矩阵 IE 以下方程中的 Phi 取自 Scott Kuindersma Frank Permenter 和 Russ Tedrake 的 稳定动态运动的有效可解二次规划 我的
  • 检查 href 中是否存在 jQuery 中的查询字符串

    我目前有一段 jQuery 用于附加带有一些位置信息的 URL jQuery a attr href function return this href location 123 abc 我的问题是大多数链接都有一个 其中使用上面的 就可以
  • 无法匹配任何路线。 URL 段:'':尝试使用子路由和 Ng2 时

    I have 以下笨蛋 https plnkr co edit PHaGNtfa0fPBgET4NEpZ p preview 这是行不通的 为了让它发挥作用 我可以评论 RouterModule forRoot path component
  • 显示带有 jQ​​uery-ui 自动完成功能的微调器

    我一直在到处搜索 但没有看到有人这样做 是否有可能拥有某种带有 jQ uery UI 自动完成功能的旋转器 加载器 1 8 获取数据时 我的解决方案是使用 ui autocomplete loading CSS 类 该类在 ajax GET
  • AngularUI Router:在调用子状态时将 url 参数传递给“抽象”状态

    我想在调用子状态时访问抽象状态内的 url 参数 stateParam 我很想知道如何做到这一点 代码在笨蛋也 http plnkr co edit L0TXx3DCBOJmh4XydXbV p preview stateProvider
  • 网页抓取 - 如何识别网页上的主要内容

    给定一个新闻文章网页 来自任何主要新闻来源 例如时报或彭博社 我想识别该页面上的主要文章内容 并丢弃其他杂项元素 例如广告 菜单 侧边栏 用户评论 在大多数主要新闻网站上都可以使用的通用方法是什么 有哪些好的数据挖掘工具或库 最好是基于Py
  • Phonegap 图像未显示

    我无法让图像在我的phonegap 版本中正常工作 我读过绝对路径可能不起作用 所以我尝试了绝对路径和相对路径 但仍然没有运气 我包括这样的图像
  • 什么是错误“类型实例化涉及 byref 类型。” F# 中的解决方法是什么

    我有一些代码包装 TA Lib 很多包装器非常相似 let sma timePeriod int data float let mutable outStartIndex 0 let mutable outNbElement 0 let m
  • Curl 和 Php 5.3.3 中的 SSL 连接错误

    我的网站自 3 年来一直运行良好 代码如下 现在突然从 2 天开始出现以下错误 SSL 连接错误 在 Curl error 中 下面是我的代码
  • 如何知道寄存器是否是“通用寄存器”?

    我试图了解寄存器必须具备什么标准才能被称为 通用寄存器 我相信通用寄存器是一个可以用于任何用途的寄存器 用于计算 将数据移入 移出等 并且是一个没有特殊用途的寄存器 现在我读到了ESP寄存器是通用寄存器 我猜是ESP寄存器可以用于任何事情
  • Ionic 2 获取离子输入值

    我正在使用 ionic 2 创建登录名 请不要只回答 您只需要添加 ngModules 属性 如果您认为这就是解决方案 请解释原因 解释一下 就像对孩子做的那样 我的代码在login ts import Component from ang
  • Android Windows:它们何时以及如何创建?

    我已经阅读了标准的 Windows 相关文档并翻阅了 一堆源代码 试图理解 Android 如何以及何时 窗口已创建 我相信我已经拥抱它并愿意 对其进行验证或更正 据我所知 只有两种方法可以获得 Window 对象的句柄 1 Activit
  • 在 ANTLR4 中如何检查行的第一个字符是否为“*”?

    我正在尝试为一种相对简单但特殊的语言编写一个解析器 简单地说 规则之一是注释行用星号表示only如果该星号是该行的第一个字符 我如何在 ANTLR4 中正式化这样的规则 我考虑过使用 START LINE COMMENT n n gt sk