- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我在 ANTLR 解析器规则上的语义谓词方面遇到了一些问题。这是我的语法,旨在识别几种不同的日期格式:
grammar sample ;
options { language=Python3; }
@parser::header {
from datetime import datetime
}
month_number returns [val] : INTEGER { 1 <= int($INTEGER.text) <= 12 }? {$val = int($INTEGER.text)} ;
day_number returns [val] : INTEGER { 1 <= int($INTEGER.text) <= 31 }? {$val = int($INTEGER.text)} ;
year_4digit returns [val] : INTEGER { 1900 <= int($INTEGER.text) <= 2100 }? {$val = int($INTEGER.text)} ;
year_2digit returns [val] : '\''? INTEGER {(int($INTEGER.text) >= 65 or int($INTEGER.text) < 40)}?
{$val = (1900 + int($INTEGER.text)) if (int($INTEGER.text) >= 65) else (2000 + int($INTEGER.text))} ;
year_digits returns [val]
: year_4digit {$val = $year_4digit.val}
| year_2digit {$val = $year_2digit.val}
;
mdy returns [val]
: month_number '-' day_number '-' year_digits {$val = datetime($year_digits.val, $month_number.val, $day_number.val)}
| month_number '/' day_number '/' year_digits {$val = datetime($year_digits.val, $month_number.val, $day_number.val)}
;
ymd returns [val]
: year_4digit '-' month_number '-' day_number {$val = datetime($year_4digit.val, $month_number.val, $day_number.val)}
| year_4digit '/' month_number '/' day_number {$val = datetime($year_4digit.val, $month_number.val, $day_number.val)}
;
date_as_numbers returns [val]
: ymd {$val = $ymd.val}
| mdy {$val = $mdy.val}
;
INTEGER: '0'..'9'+ ;
我使用以下程序进行测试:
from myPackage.sampleParser import sampleParser
from myPackage.sampleLexer import sampleLexer
from antlr4 import CommonTokenStream
from antlr4 import InputStream
date_input = InputStream("2/12/2017".lower())
lexer = sampleLexer(date_input)
stream = CommonTokenStream(lexer)
parser = sampleParser(stream)
result = parser.date_as_numbers()
print(result.val)
这会导致以下错误:
line 1:1 rule year_4digit failed predicate: { 1900 <= int($INTEGER.text) <= 2100 }?
line 1:9 rule day_number failed predicate: { 1 <= int($INTEGER.text) <= 31 }?
Traceback (most recent call last):
File "/Users/kwilliams/Library/Preferences/IntelliJIdea2017.3/scratches/scratch_1.py", line 11, in <module>
result = parser.date_as_numbers()
File "/Users/kwilliams/git/myPackage/sampleParser.py", line 482, in date_as_numbers
localctx._ymd = self.ymd()
File "/Users/kwilliams/git/myPackage/sampleParser.py", line 436, in ymd
localctx.val = datetime(localctx._year_4digit.val, localctx._month_number.val, localctx._day_number.val)
TypeError: an integer is required (got type NoneType)
所以我相信正在发生的事情是 year_4digit
中的谓词抛出异常,因为数字 2
不在其范围内,但它返回一个 无论如何,year_4digit
都匹配,但尚未填充其 val
属性,从而导致有关 NoneType
的下游错误。这是正确的吗?
如果是这样 - 什么是好的解决方案?我需要将语义谓词放在规则的前面吗?如果这是正确的解决方案,我将如何对 INTEGER
token 进行前瞻?
(另外 - 我希望能够执行 $INTEGER.int
而不是 int($INTEGER.text)
,但也许这在 Python 目标中不可用?无关紧要的小问题。)
顺便说一句,上面的语法是我真实语法的一小部分摘录,我希望有一个解决方案不需要对这部分进行重大更改,可能会导致可能需要一段时间才能解决的链式 react 。
谢谢。
最佳答案
显然,谓词嵌套得太深,导致解析器无法回溯并尝试第二种选择:
date_as_numbers returns [val]
: ymd {$val = $ymd.val} // alternaitve 1
| mdy {$val = $mdy.val} // alternaitve 2
;
当我交换替代方案时:
date_as_numbers returns [val]
: mdy {$val = $mdy.val}
| ymd {$val = $ymd.val}
;
输入“2/12/2017”
已正确解析,但“2017/12/2”
失败。
我不知道这是否是预期的行为,还是一个错误(我还没有对新的 v4 谓词做过太多事情)。你可以raise an issue关于这个。
经过一番尝试后,我通过将规则合并到 1 个大 any_date
规则中,并让这些规则以谓词开头,而不是在中间某处添加谓词,得到了一些效果(正如您自己已经暗示的那样):
grammar sample;
@parser::members {
boolean lte(Token token, int value) {
return Integer.parseInt(token.getText()) <= value;
}
boolean gte(Token token, int value) {
return Integer.parseInt(token.getText()) >= value;
}
}
date_as_numbers returns [String val]
: any_date EOF {$val = $any_date.val;}
;
any_date returns [String val]
: {gte(_input.LT(1), 1) && lte(_input.LT(1), 12)}?
INTEGER '-' day_number '-' year_digits {$val = "y=" + $year_digits.val + ", m=" + $INTEGER.text + ", d=" + $day_number.val;}
| {gte(_input.LT(1), 1) && lte(_input.LT(1), 12)}?
INTEGER '/' day_number '/' year_digits {$val = "y=" + $year_digits.val + ", m=" + $INTEGER.text + ", d=" + $day_number.val;}
| {gte(_input.LT(1), 1900) && lte(_input.LT(1), 2100)}?
INTEGER '-' month_number '-' day_number {$val = "y=" + $INTEGER.text + ", m=" + $month_number.val + ", d=" + $day_number.val;}
| {gte(_input.LT(1), 1900) && lte(_input.LT(1), 2100)}?
INTEGER '/' month_number '/' day_number {$val = "y=" + $INTEGER.text + ", m=" + $month_number.val + ", d=" + $day_number.val;}
;
month_number returns [int val]
: INTEGER {gte($INTEGER, 1) && lte($INTEGER, 12)}?
{$val = Integer.parseInt($INTEGER.text);}
;
day_number returns [int val]
: INTEGER {gte($INTEGER, 1) && lte($INTEGER, 31)}?
{$val = Integer.parseInt($INTEGER.text);}
;
year_4digit returns [int val]
: INTEGER {gte($INTEGER, 1900) && lte($INTEGER, 2100)}?
{$val = Integer.parseInt($INTEGER.text);}
;
year_2digit returns [int val]
: '\''? INTEGER {gte($INTEGER, 65) || lte($INTEGER, 39)}?
{$val = Integer.parseInt($INTEGER.text) >= 65 ? 1900 + Integer.parseInt($INTEGER.text) : 2000 + Integer.parseInt($INTEGER.text);}
;
year_digits returns [int val]
: year_4digit {$val = $year_4digit.val;}
| year_2digit {$val = $year_2digit.val;}
;
INTEGER: '0'..'9'+ ;
(抱歉,没有 python)
运行此类时:
import org.antlr.v4.runtime.*;
public class Main {
public static void main(String[] args) {
String[] tests = { "2/12/2017", "2017/12/31", "1-2-'03" };
for (String test : tests) {
sampleLexer lexer = new sampleLexer(CharStreams.fromString(test));
sampleParser parser = new sampleParser(new CommonTokenStream(lexer));
System.out.println(test + " -> " + parser.date_as_numbers().val);
}
}
}
打印以下内容:
2/12/2017 -> y=2017, m=2, d=12
2017/12/31 -> y=2017, m=12, d=31
1-2-'03 -> y=2003, m=1, d=2
我知道,这并不完美,但也许你可以稍微调整一下当前的语法并让一些东西发挥作用。
当然,您也可以放弃谓词并执行以下操作:
grammar sample;
date_as_numbers
: ymd
| mdy
| failure
;
ymd
: year '/' month '/' day
| year '-' month '-' day
;
mdy
: month '/' day '/' year
| month '-' day '-' year
;
year
: '\''? year_2digits
| NUM_4DIGITS
;
year_2digits
: NUM_1_12
| NUM_13_31
| NUM_2DIGITS
;
month
: NUM_1_12
;
day
: NUM_1_12
| NUM_13_31
;
failure
: NUM_OTHER
;
NUM_1_12
: [1-9] // 1..9
| '1' [0-2] // 10..12
;
NUM_13_31
: '1' [3-9] // 13..19
| '2' D // 20..29
| '3' [01] // 30..31
;
NUM_2DIGITS
: D D
;
NUM_4DIGITS
: '19' D D // 1900..1999
| '20' D D // 2000..2099
| '2100' // 2100
;
NUM_OTHER
: D+
;
fragment D : [0-9];
关于python - ANTLR 语义谓词 - 不阻止规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49075258/
我需要在 nginx-ingress 版本上允许来自多个来源的请求:http://localhost:4200、http://localhost:4242 等1.7.1.但我无法对多个来源执行此操作,
我正在部署我使用 APIGILITY 开发的 API到 IIS。由于 IIS 不支持 .htaccess,我试图从 .htaccess 文件的内容创建 web.config 文件。我使用 IISv7.
我正在尝试更改上面 css 样式中的“宽度”规则。在“inspect element”中你可以看到宽度是1008px。我不希望它是 1008px 但它不会让我在 css 样式中更改它你可以看到它被“删
外部css赋值有2种方法,我用的是第一种;大多数网站使用第二种方法。我想知道我是否做错了! 第一种方法: 为几乎每个 css 规则创建一个类并在任何地方使用它们。 blah blah .f_
RDF使用 WEB 标识符 (URIs) 来标识资源,使用属性和属性值来描述资源 RDF 资源、属性和属性值 RDF使用 WEB 标识符来标识事物,并通过属性和属性值来描述资源。 关于资源、属性
我想挖掘特定的 rhs 规则。文档中有一个示例证明这是可能的,但仅适用于特定情况(如下所示)。先来一个数据集来说明我的问题: input {b=100002} 0.2500000 0.250000
我想让 nginx 从网站根目录(:http://localhost:8080/)提供一个静态文件,但它为我的代理通行证提供服务;它提供“/”规则而不是“=/”。 这是我的 nginx 配置的样子:
根据gnu make documentation , 如果一个规则通过一次调用生成多个目标(例如,一个配方执行一个带有多个输出文件的工具),你可以使用 '&:' 规则语法来告诉 make。但是,当在多
我已阅读Firebase Documentation并且不明白什么是 .contains()。 以下是文档中 Firebase 数据库的示例规则: { "rules": { "rooms"
关闭。这个问题是opinion-based 。目前不接受答案。 想要改进这个问题吗?更新问题,以便 editing this post 可以用事实和引文来回答它。 . 已关闭 6 年前。 Improv
我正在尝试做一些多态性练习,但我无法弄清楚这种多态性是如何工作的。我没有找到任何关于这种练习的深入信息。希望大家能给我一些解释。 练习1: class Top { public void m(
为了调试复杂的 XSLT 转换,我将其分为几个部分:首先构建 %.1.xml,然后使用它构建 %.2.xml ,最后构建 %.3.xml。一切正常,但如果我要求 Make 构建最后一个,Make 总是
我尝试了 hacerrank 的 slove 练习 Click我不知道如何添加这些规则: ► 它可以包含 4 个一组的数字,并用一个连字符“-”分隔。 ► 不得有 4 个或更多连续重复数字。 这是我的
我正在尝试编写一个小测验,我希望“再试一次”按钮遵循与“else”之前的“if”语句相同的规则 using System; public class Program { public stat
在我的 Spring/Boot Java 项目中,我有一组服务方法,例如以下一个: @Override public Decision create(String name, String descr
我正在阅读 Covariant virtual function .上面写着 假设 B::f 覆盖了虚函数 A::f。如果满足以下所有条件,A::f 和 B::f 的返回类型可能不同: 1) The
我工作的公司想要分发(在公共(public)链接中)具有内部签名的应用程序。我很确定 Apple 否认这种事情,但我在官方文档/契约(Contract)中没有找到任何相关信息。 有谁知道它到底是如何工
我是 CSS 新手。我观察到一个奇怪的 CSS 行为,其中一个元素具有以下 CSS 属性 .container .header{ color: #FFFFFF; font-size: 2em;
这个问题在这里已经有了答案: Is there a CSS selector for elements containing certain text? (21 个答案) 关闭 7 年前。
我有以下 CSS: workoutcal.css: .errorlist{ color:red; } 以下基本模板: base.html: {% load static %} {
我是一名优秀的程序员,十分优秀!