Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >为什么添加到我的ANTLR4语法中会破坏一个无关的规则选择?

为什么添加到我的ANTLR4语法中会破坏一个无关的规则选择?
EN

Stack Overflow用户
提问于 2014-10-01 05:42:13
回答 1查看 865关注 0票数 0

我正在使用ANTLR4解析魔术卡(org.antlr:antlr4 4-运行时:4.0)。此最小化版本能够解析能力,如Enchant creatureEnchant black creature、.以及Protection from creaturesProtection from legendary creatures、.

现在我正在尝试启用Protection from black,这给我带来了问题。

我有以下的lexer和解析器语法,以及一个测试类:

莱克瑟:

代码语言:javascript
运行
AI代码解释
复制
lexer grammar OracleLexer;

Black: 'black';
Creature: 'creature';
Creatures: 'creatures';
Enchant: 'enchant';
From: 'from';
Legendary: 'legendary';
Protection: 'protection';

WS: [ \t\f\r\n]+ -> skip;

解析器:

代码语言:javascript
运行
AI代码解释
复制
parser grammar OracleParser;

options {
  tokenVocab = OracleLexer;
}

line:
  keywordAbility EOF;

keywordAbility:
  Enchant singularObject #Enchant |
    Protection From pluralObject #Protection;                   // (A)
//  Protection From (pluralObject | objectQuality) #Protection; // (B)



singularObject:
  objectQuality? Creature;

pluralObject:
  objectQuality? Creatures;



objectQuality:
  cardtypeQuality+? |
  supertypeQuality+ cardtypeQuality*? |
  colorQuality+ supertypeQuality* cardtypeQuality*?;

colorQuality:
  Black;

supertypeQuality:
  Legendary;

cardtypeQuality:
  Creature;

考试班:

代码语言:javascript
运行
AI代码解释
复制
import static java.util.Arrays.*;
import static java.util.Collections.*;

import java.util.List;

import org.antlr.v4.runtime.*;


public class OracleParserTest {
    private static final List<String> ruleNames = unmodifiableList(asList(OracleParser.ruleNames));

    public static void main(String[] args) throws Exception {
        parse("Enchant creature");
        parse("Enchant black creature");
        parse("Protection from black");
        parse("Protection from black creatures");
    }

    private static void parse(String ability) throws RecognitionException {
        OracleLexer lexer = new OracleLexer(new ANTLRInputStream(ability.toLowerCase()));
        lexer.removeErrorListeners();
        lexer.addErrorListener(new BailErrorListener());

        OracleParser parser = new OracleParser(new CommonTokenStream(lexer));
        parser.removeErrorListeners();
        parser.setErrorHandler(new BailErrorStrategy());

        RuleContext ctx = parser.line();

        System.out.println(ctx.toStringTree(ruleNames));
        ctx.inspect(ruleNames);
    }
}

在解析器中,有一个keywordAbility规则,在该规则中,我将替代(A)更改为(B),突然之间,我再也无法与Enchant black creature匹配了。以下是文本形式的所有解析树,如果有帮助的话:

代码语言:javascript
运行
AI代码解释
复制
 original strings
Enchant creature
Enchant black creature
Protection from black
Protection from black creatures

 parse trees variant (A)
(line (keywordAbility enchant (singularObject creature)) <EOF>)
(line (keywordAbility enchant (singularObject (objectQuality (colorQuality black)) creature)) <EOF>)
 does not parse - expected
(line (keywordAbility protection from (pluralObject (objectQuality (colorQuality black)) creatures)) <EOF>)

 parse trees variant (B)
(line (keywordAbility enchant (singularObject creature)) <EOF>)
 does not parse - problem!
(line (keywordAbility protection from (objectQuality (colorQuality black))) <EOF>)
(line (keywordAbility protection from (pluralObject (objectQuality (colorQuality black)) creatures)) <EOF>)

下面是Enchant black creature的堆栈跟踪

代码语言:javascript
运行
AI代码解释
复制
Exception in thread "main" org.antlr.v4.runtime.misc.ParseCancellationException
    at org.antlr.v4.runtime.BailErrorStrategy.recover(BailErrorStrategy.java:51)
    at net.slightlymagic.laterna.oracle.grammar.OracleParser.objectQuality(OracleParser.java:462)
    at net.slightlymagic.laterna.oracle.grammar.OracleParser.singularObject(OracleParser.java:235)
    at net.slightlymagic.laterna.oracle.grammar.OracleParser.keywordAbility(OracleParser.java:161)
    at net.slightlymagic.laterna.oracle.grammar.OracleParser.line(OracleParser.java:79)
    at net.slightlymagic.laterna.oracle.grammar.OracleParserTest.parse(OracleParserTest.java:49)
    at net.slightlymagic.laterna.oracle.grammar.OracleParserTest.main(OracleParserTest.java:35)
Caused by: org.antlr.v4.runtime.NoViableAltException
    at org.antlr.v4.runtime.atn.ParserATNSimulator.noViableAlt(ParserATNSimulator.java:1532)
    at org.antlr.v4.runtime.atn.ParserATNSimulator.execATNWithFullContext(ParserATNSimulator.java:816)
    at org.antlr.v4.runtime.atn.ParserATNSimulator.execATN(ParserATNSimulator.java:701)
    at org.antlr.v4.runtime.atn.ParserATNSimulator.predictATN(ParserATNSimulator.java:389)
    at org.antlr.v4.runtime.atn.ParserATNSimulator.adaptivePredict(ParserATNSimulator.java:346)
    at net.slightlymagic.laterna.oracle.grammar.OracleParser.objectQuality(OracleParser.java:440)
    ... 5 more

我如何获得语法来解析这种能力(同样如此),为什么它不能正常工作呢?

(我尝试删除BailErrorStrategy,这使它工作,但也导致90%的魔术能力解析为假阳性,并没有解释为什么这一能力以前起作用。BailErrorStrategy是否完全干扰回溯?)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-10-01 06:07:12

ANTLR 4不使用回溯(运行时库实际上不包含任何形式的此类功能代码)。

我无法在这条消息的末尾使用测试来重现这个结果。我的猜测是以下原因之一造成了这个问题:

  1. 你把BailErrorStrategy添加到你的雷克萨斯。它从未打算以这种方式使用。相反,按照my other answer中的建议将语法错误完全推迟到解析器。
  2. 您可能正在使用旧版本的ANTLR,该版本的错误已经修复。
  3. 只有在使用单独的lexer和解析器语法(测试使用组合语法)时,问题才会出现。

测试用例:

代码语言:javascript
运行
AI代码解释
复制
@Test
public void testCardParsing() throws Exception {
    String grammar =
        "grammar Oracle;\n" +
        "\n" +
        "line @init{setErrorHandler(new BailErrorStrategy());} @after {System.out.println($ctx.toStringTree(this));} :\n" +
        "  keywordAbility EOF;\n" +
        "\n" +
        "keywordAbility:\n" +
        "  Enchant singularObject #Enchant |\n" +
        "//  Protection From pluralObject #Protection;                   // (A)\n" +
        "    Protection From (pluralObject | objectQuality) #Protection; // (B)\n" +
        "\n" +
        "singularObject:\n" +
        "  objectQuality? Creature;\n" +
        "\n" +
        "pluralObject:\n" +
        "  objectQuality? Creatures;\n" +
        "\n" +
        "objectQuality:\n" +
        "  cardtypeQuality+? |\n" +
        "  supertypeQuality+ cardtypeQuality*? |\n" +
        "  colorQuality+ supertypeQuality* cardtypeQuality*?;\n" +
        "\n" +
        "colorQuality:\n" +
        "  Black;\n" +
        "\n" +
        "supertypeQuality:\n" +
        "  Legendary;\n" +
        "\n" +
        "cardtypeQuality:\n" +
        "  Creature;\n" +
        "\n" +
        "Black: 'black';\n" +
        "Creature: 'creature';\n" +
        "Creatures: 'creatures';\n" +
        "Enchant: 'enchant';\n" +
        "From: 'from';\n" +
        "Legendary: 'legendary';\n" +
        "Protection: 'protection';\n" +
        "\n" +
        "WS: [ \\t\\f\\r\\n]+ -> skip;";

    String input = "enchant creature";
    String found = execParser("Oracle.g4", grammar, "OracleParser", "OracleLexer", "line", input, true);
    assertEquals("(line (keywordAbility enchant (singularObject creature)) <EOF>)\n", found);
    assertNull(stderrDuringParse);

    input = "enchant black creature";
    found = execParser("Oracle.g4", grammar, "OracleParser", "OracleLexer", "line", input, false);
    assertEquals("(line (keywordAbility enchant (singularObject (objectQuality (colorQuality black)) creature)) <EOF>)\n", found);
    assertNull(stderrDuringParse);

    input = "protection from black";
    found = execParser("Oracle.g4", grammar, "OracleParser", "OracleLexer", "line", input, false);
    assertEquals("(line (keywordAbility protection from (objectQuality (colorQuality black))) <EOF>)\n", found);
    assertNull(stderrDuringParse);

    input = "protection from black creatures";
    found = execParser("Oracle.g4", grammar, "OracleParser", "OracleLexer", "line", input, false);
    assertEquals("(line (keywordAbility protection from (pluralObject (objectQuality (colorQuality black)) creatures)) <EOF>)\n", found);
    assertNull(stderrDuringParse);
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26142835

复制
相关文章
【计算理论】上下文无关语法 ( 语法组成 | 规则 | 语法 | 语法示例 | 约定的简写形式 | 语法分析树 )
: 有限的规则组成的集合 , 规则规定如何进行代换操作 , 规定 变量 , 终端字符 , 字符串变量 等 ;
韩曙亮
2023/03/27
2.1K0
【计算理论】上下文无关语法 ( 语法组成 | 规则 | 语法 | 语法示例 | 约定的简写形式 | 语法分析树 )
使用antlr4构造我的语法树
编译器的前端和后端。前端指的是编译器对程序代码的分析和理解。前端阶段只与语言的语法有关,而和目标机器无关。后端则是生成目标机器的目标代码有关。第一节说说编译器的前端技术。
mariolu
2020/01/13
9.2K0
Antlr4 语法解析器(下)
Antlr4 的两种AST遍历方式:Visitor方式 和 Listener方式。
awwewwbbb
2021/07/16
3.6K0
Antlr4  语法解析器(下)
为什么破坏双亲委派机制?
双亲委派机制是Java类加载器的一种基础架构,它的作用是保证Java中类的安全性和稳定性。在Java中,类加载器主要分为三种:Bootstrap ClassLoader、Extension ClassLoader和Application ClassLoader。其中,Bootstrap ClassLoader是最顶层的类加载器,Extension ClassLoader和Application ClassLoader都是由它衍生而来。在双亲委派机制下,当一个类需要被加载时,会先被Application ClassLoader加载,如果Application ClassLoader发现该类还没有被加载,则会将加载请求委派给Extension ClassLoader;Extension ClassLoader如果也没有加载过该类,再将委派请求传递给Bootstrap ClassLoader进行加载。如果Bootstrap ClassLoader成功加载了该类,就会沿着委托链返回,让Extension ClassLoader和Application ClassLoader逐一进行加载。双亲委派机制的优点是保证了类的唯一性,避免了重复加载。
疯狂的KK
2023/04/03
1K0
git .gitignore 忽略规则的匹配语法
2)以“#”开头的行都会被 Git 忽略。即#开头的文件标识注释,可以使用反斜杠进行转义;
小蔚
2020/09/07
7.9K0
如何实现一个SQL解析器
随着技术的不断的发展,在大数据领域出现了越来越多的技术框架。而为了降低大数据的学习成本和难度,越来越多的大数据技术和应用开始支持SQL进行数据查询。SQL作为一个学习成本很低的语言,支持SQL进行数据查询可以降低用户使用大数据的门槛,让更多的用户能够使用大数据。
2020labs小助手
2022/10/24
2.6K0
jsx语法规则
PlainBashC++C#CSSDiffHTML/XMLJavaJavascriptMarkdownPHPPythonRubySQL
张苹果
2022/09/22
5420
XML语法规则
1、在编写XML文档时,需要先使用文档声明来声明XML文档。且必须出现在文档的第一行。
星哥玩云
2022/09/14
1.3K0
Antlr4的相关用法
ANTLR (ANother Tool for Language Recognition) 是一个强大的解析器的生成器,可以用来读取、处理、执行或翻译结构化文本或二进制文件。他被广泛用来构建语言,工具和框架。ANTLR可以从语法上来生成一个可以构建和遍历解析树的解析器。
东风压倒西风
2022/11/23
7050
初识python ,python中的语法规则
Python  (英国发音:/ˈpaɪθən/ 美国发音:/ˈpaɪθɑːn/), 是一种面向对象的解释型计算机程序设计语言,由荷兰人Guido van Rossum于1989年发明,第一个公开发行版发行于1991年。
用户7886150
2020/11/18
7690
为什么Python中会有集合set类型?
有人提问,为什么Python有了列表list、元组tuple、字典dict这样的容器后,还要弄个集合set?
朱卫军 AI Python
2023/02/23
2720
为什么Python中会有集合set类型?
dotnet OpenXML 文本字体的选择规则
在 Office 的文本排版里面,会根据字符选择使用哪个字体插槽。也就是实际上在 Office 里面可以在一个文本段里面指定多个字体,会根据实际的字符使用不同的字体
林德熙
2020/07/28
7160
性能测试中会遇到的瓶颈
性能测试这种测试方式在发生过程中,其中一个过渡性的工作,就是对执行过程中的问题,进行定位,对功能的定位,对负载的定位,最重要的,当然就是问题中说的“瓶颈”,接触性能测试不深,更非专家,自己的理解,瓶颈产生在以下几方面:
顾翔
2020/09/04
1.9K0
Dart语法基础系列二《语法规则》
WTF,连个打印都不让写了。提示需要一个函数体去执行。dart需要mian函数入口去执行。
星宇大前端
2021/10/11
7240
Markdown简要语法规则
1. 标题 # 一级标题 ## 二级标题 ### 三级标题 一级标题 二级标题 三级标题 2. 列表 列表有有序列表与无序列表 - 无序列表1 * 无序列表2 + 无序列表3 无序列表1 无序列表2 无序列表3 1. 有序列表 2. 有序列表 3. 有序列表 4. 有序列表 有序列表 有序列表 有序列表 有序列表 3. 引用 > 引用内容 引用内容 4. 图片与链接 [csxiaoyao](www.csxiaoyao.com) ![sunshine](http://www.cs
csxiaoyao
2019/02/20
7690
正则表达式的语法规则
正则表达式(英语:Regular Expression,在代码中常简写为regex)。 正则表达式是一个字符串,使用单个字符串来描述、用来定义匹配规则,匹配一系列符合某个句法规则的字符串。在开发中,正则表达式通常被用来检索、替换那些符合某个规则的文本。
Lcry
2022/11/29
6250
(五)jsx 语法规则
# 🍈 一、什么是 jsx jsx 全称叫做 JavaScript XML 是React 定义的一种类似于 XML 的 js 扩展语法:JS+XML 本质是 React.createElment(标签名, 标签属性, 标签体内容) 方法的语法糖 # 🍧二、什么是 XML XML 早期用于存储和传输数据 <student> <name>TOM</name> <age>18</age> </student> # ☕三、jsx 语法规则 数据写死 // 创建虚拟 DOM const VDOM =
老怪兽
2023/02/21
3830
探究Presto SQL引擎(1)-巧用Antlr
自2014年大数据首次写入政府工作报告,大数据已经发展7年。大数据的类型也从交易数据延伸到交互数据与传感数据。数据规模也到达了PB级别。
2020labs小助手
2021/08/10
2.2K0
你从一个世界来到我的世界-TAU下
之前我们已经赘述了4G的附着过程(关键字attach获取),简单的整理了网络身份ID——GUTI、P-TMSI以及他们的mapping关系(关键字id获取),然后讲述了4G中移动性管理的TAU上——4G内部的TAU消息(以Inter-MME with SGW change为例,关键字tau获取);接下来我们继续简单赘述一下TAU的其他相关内容。
琉璃康康
2022/04/19
8550
你从一个世界来到我的世界-TAU下
点击加载更多

相似问题

无关规则破坏ANTLR4语法

12

Antlr4:语法错误:无关输入...查找规则元素时需要GT

10

ANTLR4语法冲突规则

11

将添加到我的podfile中会破坏构建(未找到库)

311

ANTLR4语法无关/不匹配输入误差

13
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
社区富文本编辑器全新改版!诚邀体验~
全新交互,全新视觉,新增快捷键、悬浮工具栏、高亮块等功能并同时优化现有功能,全面提升创作效率和体验
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文