我有一个语法,当解析在一次传递(整个文件)很好。
现在我希望将解析分解成组件。并在子库上运行解析器。我遇到了一个问题,我假设其他解析子库的人会看到下面的规则:
thing : LABEL? THING THINGDATA thingClause?
//{System.out.println("G4 Lexer/parser thing encountered");}
;
...
thingClause : ',' ID ( ',' ID)?
;
当上面的规则从一个顶级的开始规则解析到EOF时,一切都很好。当解析为子规则(而不是解析为EOF)时,解析器在没有thing子句时会感到不安,因为它希望看到“,”字符或EOF字符。
第8行:0不匹配的输入“%”应为{,“,”}
当我解析到EOF时,%被正确地解析到另一个“thing”组件中,因为顶层规则查找:
toprule : thing+
| endOfThingsTokens
;
内源性火灾发生在EOF之前...所以我想这就是顶级规则起作用的原因。
为了解析子库,我希望ANTLR4解析器接受或忽略%令牌,并说“OK,我们没有看到一个ThingClause”,然后重置令牌流,这样下一个thing对象就可以由解析器的另一个实例解析。
在本例中,我可以更改lexer,将换行符传递给解析器,我目前在lexer语法中跳过了这一点。这将需要许多其他更改来接受令牌流中的换行符,而这些更改目前是不需要的。
本质上,我需要一些方法来使规则具有一个“记录结束”标记。但我想知道是否有某种方法可以用语义谓词规则来解决这个问题。
类似于:
thing : { if comma before %}? LABEL? THING THINGDATA thingClause?
| LABEL? THING THINGDATA
;
...
thingClause : ',' ID ( ',' ID)?
;
解析器将(有效地)在令牌流中向前看,以确定是否可以满足当前规则。然后消耗相应的令牌。如果任何前瞻令牌仍未被使用,解析器将查找另一个规则来使用这些前瞻令牌和其他前瞻令牌。
ThingClause?
元素不匹配时,将导致解析器中未使用的标记。因此,您看到的错误。
解析器前瞻依赖于数据。这意味着对规则元素的求值可以很容易地向解析器中读取比当前规则可能消耗的更多的令牌。
虽然谓词可能有所帮助,但它不会使问题具有确定性。也就是说,即使解析器匹配非谓词alt,它也很可能读取到解析器中的令牌比该alt所能消耗的更多。
避免这种不确定性的唯一方法是将
标记预注入到子规则边界的标记流中。
我所开发的ANTR4语法。在解析字符串期间 时间;25 10 * * *;' faccalc_minus1_cron.out.'yyyyMMdd。嗯;美国/New_York 我有以下错误 表达式中的字符无效!表达式:;'无效字符:;'无关输入“;”应为{“”,整数,“-”,“/”,“,”},缺少“;”“\uu”处的时区格式不正确:faccalc\u minus1 我不理解为什么,因为正则表达式规则
我试图以C#为目标,使用Antlr4解析一个日期。在我的情况下,有效日期应具有以下内容 采用格式 年份只能有4位数字 月和日只能有2位 我知道类似的问题已经出现了,但它们的解决方案似乎对我不起作用 如何创建将解析日期的antlr4语法 ANTLR:识别日期和数字的最简单方法? 我在某个地方读到过,有一种类似优先级的解析,其中基于语法文件如何编写的顶级规则首先被评估。因此,考虑一下,除了日期,我的语
有什么方法可以让ANTLR4自动删除生成的解析树中的冗余节点吗? 更具体地说,我一直在试验GLSL的语法,由于自动处理操作符优先级所需的规则转发,您最终会在解析树中看到长的线性“表达式”序列。 大多数生成的树节点都只是简单地“转发到下一个优先级”,所以不要提供任何有用的语法信息--你只需要每个序列中最后一个表达式节点(即规则转发停止的点),或者它成为一个实际的树节点并拥有多个子节点的点(即在源中遇
在我刚刚编写的一个测试解析器中,我遇到了一个奇怪的问题,我不太明白。 将其简化为显示问题的最小示例,让我们从以下语法开始: 这是语法的变化: 突然间,相同的测试输入被错误地分解成两个statement_list,每个statement_list都继续到一个带有“missing”;“警告,第一个返回“z=”的不完整的assignment_statement,第二个返回“x+”的不完整的assignm
我在调试一个ANTLR语法时遇到了问题,我正在为Gameboy程序集工作。它似乎工作正常,但由于某些原因,它不能在某些边缘情况下处理十六进制的0x表示法。 如果我的输入字符串是“JR0x10”,antlr将失败,并出现'No Valide alternative at input‘错误。按照我的理解,这意味着我要么没有解析令牌流的规则,要么没有正确理解'0x'。如果我使用“JR$10”(我支持的替
如果在antlr4 lexer中有一个ONELINE_STRING片段规则标识一行上的一个简单引号字符串,那么如何在lexer中创建一个更通用的字符串规则,该规则将相邻的ONELINE_STRING连接起来(即,只要它们都在不同的行上开始,仅用空格和/或注释分隔)? 即, 将被解析为两个字符串标记,“foo”后跟“bar” 同时: 示例1: Sample3(注意,'output'是该语言中的关键字