- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
Antlr4中的ErrorListener机制非常适合记录和分析语法错误,因为语法错误是在解析过程中发生的,但是对于解析完成后的批处理错误,它可能会变得更好。解析完成后,您可能想处理错误的原因有很多,包括:
public class CollectionErrorListener extends BaseErrorListener {
private final List<SyntaxError> errors = new ArrayList<SyntaxError>();
public List<SyntaxError> getErrors() {
return errors;
}
@Override
public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine, String msg, RecognitionException e) {
if (e == null) {
// e is null when the parser was able to recover in line without exiting the surrounding rule.
e = new InlineRecognitionException(msg, recognizer, ((Parser)recognizer).getInputStream(), ((Parser)recognizer).getContext(), (Token) offendingSymbol);
}
this.errors.add(new SyntaxError(msg, e));
}
}
public class InlineRecognitionException extends RecognitionException {
public InlineRecognitionException(String message, Recognizer<?, ?> recognizer, IntStream input, ParserRuleContext ctx, Token offendingToken) {
super(message, recognizer, input, ctx);
this.setOffendingToken(offendingToken);
}
}
public class SyntaxError extends RecognitionException {
public SyntaxError(String message, RecognitionException e) {
super(message, e.getRecognizer(), e.getInputStream(), (ParserRuleContext) e.getCtx());
this.setOffendingToken(e.getOffendingToken());
this.initCause(e);
}
}
CollectionErrorListener collector = new CollectionErrorListener();
parser.addErrorListener(collector);
ParseTree tree = parser.prog();
// ... Later ...
for (SyntaxError e : collector.getErrors()) {
// RecognitionExceptionUtil is my custom class discussed next.
System.out.println(RecognitionExceptionUtil.formatVerbose(e));
}
// The following doesn't work if you are not reporting during the parse because the
// parser context is lost from the RecognitionException "e" recognizer.
List<String> stack = ((Parser)e.getRecognizer()).getRuleInvocationStack();
// Pass in the context from RecognitionException "e" to get the rule invocation stack
// after the parse is finished.
List<String> stack = ((Parser)e.getRecognizer()).getRuleInvocationStack(e.getCtx());
public class RecognitionExceptionUtil {
public static String formatVerbose(RecognitionException e) {
return String.format("ERROR on line %s:%s => %s%nrule stack: %s%noffending token %s => %s%n%s",
getLineNumberString(e),
getCharPositionInLineString(e),
e.getMessage(),
getRuleStackString(e),
getOffendingTokenString(e),
getOffendingTokenVerboseString(e),
getErrorLineStringUnderlined(e).replaceAll("(?m)^|$", "|"));
}
public static String getRuleStackString(RecognitionException e) {
if (e == null || e.getRecognizer() == null
|| e.getCtx() == null
|| e.getRecognizer().getRuleNames() == null) {
return "";
}
List<String> stack = ((Parser)e.getRecognizer()).getRuleInvocationStack(e.getCtx());
Collections.reverse(stack);
return stack.toString();
}
public static String getLineNumberString(RecognitionException e) {
if (e == null || e.getOffendingToken() == null) {
return "";
}
return String.format("%d", e.getOffendingToken().getLine());
}
public static String getCharPositionInLineString(RecognitionException e) {
if (e == null || e.getOffendingToken() == null) {
return "";
}
return String.format("%d", e.getOffendingToken().getCharPositionInLine());
}
public static String getOffendingTokenString(RecognitionException e) {
if (e == null || e.getOffendingToken() == null) {
return "";
}
return e.getOffendingToken().toString();
}
public static String getOffendingTokenVerboseString(RecognitionException e) {
if (e == null || e.getOffendingToken() == null) {
return "";
}
return String.format("at tokenStream[%d], inputString[%d..%d] = '%s', tokenType<%d> = %s, on line %d, character %d",
e.getOffendingToken().getTokenIndex(),
e.getOffendingToken().getStartIndex(),
e.getOffendingToken().getStopIndex(),
e.getOffendingToken().getText(),
e.getOffendingToken().getType(),
e.getRecognizer().getTokenNames()[e.getOffendingToken().getType()],
e.getOffendingToken().getLine(),
e.getOffendingToken().getCharPositionInLine());
}
public static String getErrorLineString(RecognitionException e) {
if (e == null || e.getRecognizer() == null
|| e.getRecognizer().getInputStream() == null
|| e.getOffendingToken() == null) {
return "";
}
CommonTokenStream tokens =
(CommonTokenStream)e.getRecognizer().getInputStream();
String input = tokens.getTokenSource().getInputStream().toString();
String[] lines = input.split(String.format("\r?\n"));
return lines[e.getOffendingToken().getLine() - 1];
}
public static String getErrorLineStringUnderlined(RecognitionException e) {
String errorLine = getErrorLineString(e);
if (errorLine.isEmpty()) {
return errorLine;
}
// replace tabs with single space so that charPositionInLine gives us the
// column to start underlining.
errorLine = errorLine.replaceAll("\t", " ");
StringBuilder underLine = new StringBuilder(String.format("%" + errorLine.length() + "s", ""));
int start = e.getOffendingToken().getStartIndex();
int stop = e.getOffendingToken().getStopIndex();
if ( start>=0 && stop>=0 ) {
for (int i=0; i<=(stop-start); i++) {
underLine.setCharAt(e.getOffendingToken().getCharPositionInLine() + i, '^');
}
}
return String.format("%s%n%s", errorLine, underLine);
}
}
最佳答案
我将这些建议发布到了Antlr4 GitHub问题列表中,并收到了以下回复。我相信ANTLRErrorListener.syntaxError方法包含冗余/令人困惑的参数,并且需要大量API知识才能正确使用,但是我理解该决定。这是问题的链接和文本回复的副本:
来自:https://github.com/antlr/antlr4/issues/396
关于您的建议:
The RecognitionException is non-null for all syntax errors except when we discover mismatched token errors that we can recover from in-line, without returning from the surrounding rule (via the single token insertion and deletion mechanism).
关于java - 通过ErrorListener累积/收集错误以在解析后进行处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20828864/
美好的一天! 我正在制作一个出勤检查程序,单击一次时显示橙色按钮,单击两次时显示红色按钮,单击 3 次时显示黑色按钮。我在如何累积 getClickCount() 值方面遇到问题,因为对于按钮要注册
我似乎无法在 Adobe 网站上找到明确的答案。使用 ColdFusion 10,11 甚至 2016,更新(修补程序)是否累积? 例如,ColdFusion 的修补程序高达 hotfix_023
我是随机森林新手,我有一个关于回归的问题。我正在使用 R 包 randomForests 来计算 RF 模型。 我的最终目标是选择对预测连续性状很重要的变量集,因此我正在计算一个模型,然后删除准确度平
目前我们有一个发布/消费者服务,消费者将收到的消息写入 AWS S3。我们目前每月编写超过 100.000.000 个对象。但是,我们可以根据一些规则对这些消息进行分组,以节省一些钱。这些规则可以是这
假设我有一个二叉树: data BinTree a = Nil | Branch a (BinTree a) (BinTree a) 我想在这样的结构上做一个累积映射: mapAccum ::
我正在使用内核估计,我应用了 density函数从 R 到我的数据文件(双变量),经过几次统计处理后,我需要转换这些数据,这就是我的问题: 是否有非参数方法的逆累积分布函数? 我尝试过 Google、
不确定以前是否有人问过这个问题,尝试搜索它但找不到任何相关内容。 我试图获得一个累积的字符串聚合,即仅运行不同值的聚合。这是我正在寻找的结果的示例。 我尝试使用 string_agg 函数,但它仅在用
我想找到累积的 bind.rows。这是我想要实现的小例子。我将使用 dslabs 包中的 gapminder 数据集进行演示。 library(tidyverse) library(dslabs)
在 Linux 中使用 tomcat 进程时,我们观察到时间字段显示5506:34(累积 CPU 时间)。在探索时,这是在进程的整个生命周期中运行所花费的 CPU 时间的百分比。 由于这是一个 Jav
我有一些数据可以使用 pyparsing 中的 OneorMore 函数进行解析。比如, fun = OneorMore( foo.setResultsName("foo") + bar.setRe
我试图弄清楚是否有一种简单的方法可以解决 pandas 的以下问题。假设我有四个容器,A、B、C、D,每个容器都有特定的体积。假设我现在得到了一定量的液体,我想用它来填充这些容器。我怎样才能想出一个“
我正在尝试编写一个函数来检测所有上升沿 - 向量中值超过特定阈值的索引。这里描述了类似的东西:Python rising/falling edge oscilloscope-like trigger
这个问题在这里已经有了答案: Multiplying elements of a column in skipping an element after each iteration (3 个答案)
有没有办法获取数据框中每一行的值计数? |f1|f2| ------- v1 | a value_counts -> {a:1} v2 | a value_counts -> {a:2} v3 |
我目前正在尝试对我正在构建的计算器(使用复合模式)进行测试。第一种方法应该添加 75 美元,效果很好,但是当第二种方法运行时,“服务”被重置并且有0 美元作为工作成本。如果我将这两种方法合二为一,那么
我有一个如下所示的文档: 数据.txt 100, "some text" 101, "more text" 102, "even more text" 我使用正则表达式处理它并返回一个新的处理文档,如
假设我有这个: function getAllPromises(key: string, val: any): Promise { const subDeps = someHash[key]; c
我在 mysql 中有表“cumul_sum”,我想根据条件划分“cumulative”列,即如果此列中的值 >= 70,则这些值应存储在名为“others”的新列中"并且前面应该存放对应的sku_i
我正在做一个用 C++ 刺激 ATM 的项目,但在使用累加器时遇到了一些问题,我的问题是:我正在使用开关(这里是情况 1)来更改在包含的函数中声明的 2 个变量的值switch(),但是值只在情况 1
我希望能够使用 accumulate 对 vector 中的每隔一对元素进行累加。我尝试了以下但没有成功,为非空、非零 vector 返回错误 return std::accumulate(vec.b
我是一名优秀的程序员,十分优秀!