我正在为给定的语言开发语法。 我相信我提出的语法应该有用 - 但是Antlr4有不同意见。鉴于错误,它似乎缺少回溯。但是Antlr4应该在没有它的情况下进行解析......
每个示例都应该只有一个解决方案。在解析过程中存在歧义,但除了一个选项之外的所有选项都应该是死路一条。所以我希望解析器返回并尝试下一个可能的方法。但它只报告语法错误。
语法快速摘要: 有些元素由'#'分隔。在一个元素之后,可能会有一个可选的跳转,由一个'='表示。如果元素本身包含'#'或'=',则通过复制它们来转义它们。 为避免歧义,不允许元素以“#”结尾。因此'###'始终是分隔符,然后是下一个元素的转义第一个字符。 '####'不是分隔符,只是在名称中有两个转义'#'。
语法:
private void filterWorker_CompleteWork(object sender, RunWorkerCompletedEventArgs e)
{
PanelLoading = false;
if (e.Error == null)
{
if (e.Cancelled) return;
var products = (e.Result) as List<ProductDTO>;
Products = products;
}
else
{
LogHelper.Log(e.Error);
}
}
测试,解析器错误为注释
grammar ConfigPath;
configpath: toplevelement subprojectelement* EOF;
subprojectelement: '#' path jump?;
toplevelement: '#' path jump?;
jump: jumpcommand '=' jumpdestination;
jumpcommand: '#d' | '#devpath';
jumpdestination: NONHASHCHAR+;
path: pathelement ( '/' pathelement)*;
pathelement: escapedCharacterHash* escapedCharacter ;
escapedCharacterHash: escapedCharacter | '##';
escapedCharacter: NONHASHCHAR | '==';
NONHASHCHAR: ~('#' | '/' | '=' );
HASH: '#';
EQ: '=';
由于pathelement不能以散列结束,因此三重散列中的第一个应该关闭toplevelelement并启动子项目元素,该子项目以##
开头@Test
public void testTripleHash() throws Exception {
ConfigpathContext c = parse("#BU/ConfigPath###sub");
// line 1:16 extraneous input '#' expecting {'##', '==', NONHASHCHAR}
Assert.assertEquals( "#BU/ConfigPath", c.toplevelement().getText() );
Assert.assertEquals( "###sub", c.subprojectelement().get(0).path().getText() );
}
有没有办法改变语法来接受测试? 或者Antlr4是不是能够解析这样的语法?具有回溯功能的Antlr3会找到解决方案吗?
答案 0 :(得分:0)
语法错了 - 感谢cantSleepNow说明了这一点。
虽然我还没有理解问题的每一个细节,但它似乎与Lexer中的含糊不清有关。解析器能够通过替代回溯来解决歧义,但Lexer无法解决。
所以这是工作语法:
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
tips = sns.load_dataset("tips")
sns.stripplot(x="day", y="total_bill", hue="smoker",
data=tips, jitter=True,
palette="Set2", split=True,linewidth=1,edgecolor='gray')
# Get the ax object to use later.
ax = sns.boxplot(x="day", y="total_bill", hue="smoker",
data=tips,palette="Set2",fliersize=0)
# Get the handles and labels. For this example it'll be 2 tuples
# of length 4 each.
handles, labels = ax.get_legend_handles_labels()
# When creating the legend, only use the first two elements
# to effectively remove the last two.
l = plt.legend(handles[0:2], labels[0:2], bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.)