- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在编写一种音乐语言到另一种音乐语言的翻译器(ABC 到 Alda)的过程中,作为学习 Raku DSL 能力的借口,我注意到似乎没有办法终止 。解析
!这是我缩短的演示代码:
#!/home/hsmyers/rakudo741/bin/perl6
use v6d;
# use Grammar::Debugger;
use Grammar::Tracer;
my $test-n01 = q:to/EOS/;
a b c d e f g
A B C D E F G
EOS
grammar test {
token TOP { <score>+ }
token score {
<.ws>?
[
| <uc>
| <lc>
]+
<.ws>?
}
token uc { <[A..G]> }
token lc { <[a..g]> }
}
test.parse($test-n01).say;
这是 Grammer::Tracer 显示的最后一部分,它演示了我的问题。
| score
| | uc
| | * MATCH "G"
| * MATCH "G\n"
| score
| * FAIL
* MATCH "a b c d e f g\nA B C D E F G\n"
「a b c d e f g
A B C D E F G
」
在倒数第二行,“FAIL”一词告诉我 .parse 运行无法退出。我想知道这是否正确? .say 显示了应有的所有内容,所以我不清楚 FAIL 的真实性如何?问题仍然是,“如何正确编写一个语法来解析多行而不出错?”
最佳答案
当您使用语法调试器时,它可以让您准确地看到引擎如何解析字符串 - 失败是正常的,也是预料之中的。例如,考虑匹配 a+b*
与字符串 aab
。您应该获得 'a' 的两个匹配项,然后失败(因为 b
不是 a
),但随后它将使用 b
重试。并成功匹配。
如果您与 ||
进行交替,可能会更容易看到这一点(强制执行命令)。如果你有
token TOP { I have a <fruit> }
token fruit { apple || orange || kiwi }
当你解析句子“I have a kiwi”时,你会看到它首先匹配“I have a”,然后是“apple”和“orange”两次失败,最后是“kiwi”匹配。
现在让我们看看您的案例:
TOP # Trying to match top (need >1 match of score)
| score # Trying to match score (need >1 match of lc/uc)
| | lc # Trying to match lc
| | * MATCH "a" # lc had a successful match! ("a")
| * MATCH "a " # and as a result so did score! ("a ")
| score # Trying to match score again (because <score>+)
| | lc # Trying to match lc
| | * MATCH "b" # lc had a successful match! ("b")
| * MATCH "b " # and as a result so did score! ("b ")
…………… # …so forth and so on until…
| score # Trying to match score again (because <score>+)
| | uc # Trying to match uc
| | * MATCH "G" # uc had a successful match! ("G")
| * MATCH "G\n" # and as a result, so did score! ("G\n")
| score # Trying to match *score* again (because <score>+)
| * FAIL # failed to match score, because no lc/uc.
|
| # <-------------- At this point, the question is, did TOP match?
| # Remember, TOP is <score>+, so we match TOP if there
| # was at least one <score> token that matched, there was so...
|
* MATCH "a b c d e f g\nA B C D E F G\n" # this is the TOP match
这里的失败是正常的:在某些时候我们会用完 <score>
代币,所以失败是不可避免的。当这种情况发生时,语法引擎可以继续处理<score>+
之后的任何内容。在你的语法中。由于没有任何内容,该失败实际上会导致整个字符串的匹配(因为 TOP
与隐式 /^…$/
匹配)。
此外,您还可以考虑使用自动插入 <.ws>* 的规则重写语法(除非重要的是它只能是单个空格):
grammar test {
rule TOP { <score>+ }
token score {
[
| <uc>
| <lc>
]+
}
token uc { <[A..G]> }
token lc { <[a..g]> }
}
此外,IME,您可能还想为 uc/lc 添加一个原始 token ,因为当您有 [ <foo> | <bar> ]
时您总是会遇到其中一个未定义的情况,这可能会使在操作类中处理它们有点烦人。您可以尝试:
grammar test {
rule TOP { <score> + }
token score { <letter> + }
proto token letter { * }
token letter:uc { <[A..G]> }
token letter:lc { <[a..g]> }
}
$<letter>
将始终以这种方式定义。
关于parsing - 在 EOS(字符串结尾)处停止 Raku 语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59483099/
这个问题已经有答案了: Can a shell script set environment variables of the calling shell? [duplicate] (20 个回答)
我想用 Python 为 eOS Luna 上的万神殿面板制作一个简单的小程序。我找不到任何有关 API 的文档。在一些论坛上有人建议我应该使用与 Gnome 或 Unity 相同的过程。然而,我尝试
如果您将输入编码为 std::istream_iterator ii(std::cin); std::istream_iterator eos; std::for_each(ii,eos,record
尝试即时切换输出文件,但无法处理 EOS。 http://gstreamer-devel.966125.n4.nabble.com/Dynamically-updating-filesink-loca
我正在尝试从包含非常大数据的表中获取数据。我正在使用 Java Webobject 和 EOmodel。当我尝试使用索引列获取时,我能够在不到 2 秒的时间内获得结果。但是当我尝试使用任何其他列进行搜
我们正在使用 EO.pdf 16,我们有 body 标签的 css body { background-image: url(../images/background.jpg); background
我在窗口内使用 EO webView 来加载 HTML 页面。即使我在页面中使用以下内容,页面似乎也会缓存。如何确保每次加载页面时都进行硬刷新? 我在 Windows 窗体中为“PageRefresh
我正在用另一个文件中的音乐替换我的视频的音轨。所以我修改了标准ExtractDecodeEditEncodeTest代码(来自 bigflake)以便音频 MediaExtractor是从所说的“另一
我正在尝试使用 GStreamer 1.8.2 和 Python 3.5 创建一个动态管道。目标是能够播放一些视频并在 EOS 上更改它,以类似于使用 about-to-finish of playb
在这个函数中,我该怎么做才能让父级停止尝试从管道读取数据。 IE。如果我运行命令 ls | grep test grep不会输出test和test.c然后等待用户输入? pipe(pipefd); i
我开始全神贯注于转换器架构,但有些事情我还无法掌握。 在无解码器的转换器中,例如 BERT,标记器总是在句子前后包含标记 CLS 和 SEP。我知道 CLS 既充当 BOS 又充当提供分类信息的单个隐
我正在尝试在 vm(使用 vmware 工作站)上运行的 Arista 交换机中配置以太网接口(interface)。我能够根据给定的用户 guid 配置管理接口(interface),但是在使用相同
我写了一个v4l2src同时显示和录制的代码。我的管道看起来像: / [queue] ! [videosink] v4l2src ! tee !
我正在寻找一种能够从 delphi 控制我的佳能或尼康相机的方法,基本上我需要找到一种方法来在相机与 USB 连接时接收新图像,即检测何时拍摄新照片,以便我可以在我的应用程序中采取措施,例如裁剪图像、
我正在尝试使用 gstreamer 从源中获取多个快照。使用以下代码,我成功获取了 9 个文件,但从源中获取了 EOS(这实际上是正常的,这是由 num-buffers 参数引起的): #includ
我们正在使用佳能eos sdk 2.14 进行直播和拍摄。相机是佳能1200D 以下是相机设置: 直播模式:启用 自动对焦模式:灵活 下面是代码 import java.awt.image.Buffe
我想从 Deleted 项目中的 Recoverable 项目文件夹中获取事件。 我们是否支持 rest API 来访问可恢复文件夹中的这些邮件/日历/联系人? 我找不到任何关于它的文章,也没有在 o
当我运行我的模拟器设备时,我得到了模拟器的输出,但我收到了以下错误: java.io.IOException: EOF at com.android.ddmlib.AdbHelper.read
谁能帮我解析这个输出以显示总分钟数? 这是命令(除格式化外按预期工作): ps -eo pid,etime,command | grep some_process | grep -v grep | a
我正在尝试使用 EOS CDT(合约开发工具包)。 我已经从 github 下载并安装了存储库,并习惯于按照 eos.io 开发页面上的指示执行以下命令。 https://developers.eos
我是一名优秀的程序员,十分优秀!