raku - 解析模块规范的语法
问题描述
Raku 模块可以用不同的方式指定,例如:
MyModule
MyModule:ver<1.0.3>
MyModule:ver<1.0.3>:auth<Name (email@example.com)>;
MyModule:ver<1.0.3>:auth<Name <email@example.com>>;
我编写了以下grammar
内容来解析模块规范,该规范适用于大多数规范,但如果auth
字段包含<
or则失败>
。在这种情况下,如何修复语法以匹配?
我不知道如何说匹配介于两者之间的所有内容,<
包括>
任何<
和>
。
#!/usr/bin/env perl6
grammar Spec {
token TOP { <spec> }
token spec { <name> <keyval>* }
token name { [<-[./:<>()\h]>+]+ % '::' }
token keyval { ':' <key> <value> }
proto token key { * }
token key:sym<ver> { <sym> }
token key:sym<version> { <sym> }
token key:sym<auth> { <sym> }
token key:sym<api> { <sym> }
token key:sym<from> { <sym> }
# BUG: fix specs that contains '<>' inside value;
token value { '<' ~ '>' $<val>=<-[<>]>* | '(' ~ ')' $<val>=<-[()]>* }
}
my \tests = (
'MyModule:ver<1.0.3>:auth<Name (email@example.com)>',
'MyModule:ver<1.0.3>:auth<Name <email@example.com>>',
);
for tests -> \spec {
say so Spec.parse: spec;
}
# Output:
True
False
解决方案
如果您知道内部字段基本上与值标记的格式相同,则可以递归匹配值与$<val>=[.*? <value>?]
. 这甚至可以让您单独捕获内部字段的内容:
token value { '<' ~ '>' $<val>=[.*? <value>?] | '(' ~ ')' $<val>=<-[()]>* }
如果您不想要内部内容,则可以使用递归<~~>
代替<value>
token value { '<' ~ '>' $<val>=[.*? <~~>?] | '(' ~ ')' $<val>=<-[()]>* }
推荐阅读
- angular - 如何仅在 noUISlider 标签的 [tooltips] 中添加格式化程序?
- android - 我是否需要为每个 recyclerview 创建适配器
- node.js - 如何使用 pm2 deploy 在远程服务器上部署项目?
- r - 将字段名转换为特定变量的列名,并用一定的逻辑填充它们
- sql-server - 如何在条件下正确使用 AND / OR
- android-emulator - AndroidViewClient - 如何在 Android 虚拟设备启动过程完成时收到通知?
- javascript - 解构中未定义的默认值
- automata - 如何判断 DFA 是否接受空字符串?
- sql - 通过在 Oracle 中对一列进行分组,将数据从一个表插入到另一个表
- java - 如何从 IE11 一键运行我的 Java 应用程序?