当前位置: 首页 > 知识库问答 >
问题:

perl6语法,不确定示例中的某些语法

公西姚石
2023-03-14
token string { <quote> {} <quotebody($<quote>)> $<quote> }
token quotebody($quote) { ( <escaped($quote)> | <!before $quote> . )* }

问题2B:如果我想指出“char that not before quote”,我是否应该使用“.<!before$quote>”而不是“<!before$quote>”。??

token escaped($quote) { '\\' ( $quote | '\\' ) } # I think this is a function;

共有1个答案

酆高翰
2023-03-14

TL;@BriandFoy博士提供了一个容易理解的答案。但这里有他没有提到的龙。还有漂亮的蝴蝶。这个答案很深入。

问题1:令牌中的这个{}在做什么?

它是一个代码块1,2,3,4

他所说的“regex引擎”是指NQP中的regex/语法引擎,它是Rakudo Perl 6编译器的一部分。3

他所说的“匹配变量”是指存储匹配结果捕获的变量:

>

  • 当前匹配变量$/

    他所说的“认为必要”是指regex/grammar引擎在匹配过程中的每一步之后都会对是否值得进行发布工作进行保守的调用。我所说的“保守”是指引擎经常避免发布,因为它会减慢速度,而且通常是不必要的。不幸的是,它有时过于乐观何时发布实际上是必要的。因此,程序员有时需要通过显式插入代码块来进行干预,以强制发布匹配变量(以及针对其他变量的其他技术5)。随着时间的推移,regex/grammar引擎可能会在这方面有所改进,减少需要人工干预的场景。如果您希望帮助改进这一点,请为现有的相关bug创建对您重要的测试用例。5

    这里的命名捕获$ 就是这种情况。

    据我所知,所有子匹配变量在直接写入regex时都正确地引用了它们捕获的值,而没有周围的构造。这是有效的:

    my regex quote { <['"]> }
    say so '"aa"' ~~ / <quote> aa $<quote> /; # True
    
    token string { <quote> {} <quotebody($<quote>)> $<quote> }
    

    问题2a:<>内部的转义($quote)将是一个regex函数,对吗?它以$quote作为参数

    这是一个很好的第一近似值。

    更具体地说,形式为 的regex原子是对方法foo的调用。

    say Method ~~ Regex; # False
    say WHAT token { . } # (Regex)
    say Regex ~~ Method; # True
    say / . / ~~ Method; # True
    

    不,形式为 的regex原子不会返回另一个regex。

    相反,它调用一个方法,该方法将/应该返回match对象。

    如果调用的方法是regex,P6将确保regex自动生成并填充match对象。

    如果匹配不成功,引擎可能会回溯,撤消以前的更新;因此,解析树可以随着匹配的进行而动态地增长和收缩。

    问题2B:如果我想指出“char不在引号之前”,我是否应该使用。<!在$quote>之前,而不是<!在$quote>之前。??

    是的。

    say token { . } ~~ Regex;   # True
    say Regex       ~~ Method;  # True
    say Method      ~~ Routine; # True
    

    regex正文中的代码({...}位)(在本例中,代码是标记{.}中唯一的.,它是一个与单个字符匹配的regex原子)是用P6 regex“俚语”编写的,而方法例程正文中使用的代码是用主P6“俚语”编写的。4

    regex tilde(~)运算符是专门为这个问题所涉及的示例中的解析而设计的。它读起来更好,因为它可以立即识别,并将开头和结尾的引号放在一起。更重要的是,它可以在失败的情况下提供一个可理解的错误消息,因为它可以说出它正在寻找的结束分隔符。

    但是,如果在regex中插入代码块(有没有代码),就在regex~运算符旁边(在它的两边),则必须考虑一个关键问题。您将需要对代码块进行分组,除非您特别希望代码块将其视为自己的原子。例如:

    token foo { <quote> ~ $<quote> {} <quotebody($<quote>) }
    

    将匹配一对 ,它们之间没有任何内容。(然后尝试匹配 。)

    相反,这里有一种方法可以在string::simple::grammary语法中复制string标记的匹配行为:

    token string { <quote> ~ $<quote> [ {} <quotebody($<quote>) ] }
    

    12002年,Larry Wall写道:“regex调用Perl代码需要像Perl代码调用regex一样容易。”计算机科学家注意到,在传统的正则表达式中间不能有过程代码。但是Perls很久以前就引导了向非传统正则的转变,而P6已经得出了合乎逻辑的结论--在正则中插入任意过程代码只需一个简单的{...}即可。语言设计和regex/grammar engine实现3确保了regex中传统样式的纯声明性区域能够被识别,因此可以将正式的正则表达式理论和优化应用于它们,但是也可以插入任意的正则过程代码。简单的用途包括匹配逻辑和调试。但天空是极限。

    一个关键的区别是,regex语言及其相关的regex/语法引擎,以及与之合作的主要语言(在Rakudo的情况下是Perl6)在控制方面是等价的。这是Larry Wall最初2002年关于Regex和“富语言”之间集成的愿景的一个实现。每种语言/运行时都可以调用另一种语言/运行时,并通过高级FFI进行通信。因此,它们可以看起来是,可以表现为,实际上是一个由协作语言和协作运行时组成的单一系统。

    (P6设计使得所有语言都可以通过两个互补的P6 FFI(元模型FFI6Model和/或C调用约定FFI NativeCall)显式地设计或重新装配,以“丰富”的方式进行合作。)

    4P6语言实际上是一起使用的子语言--也就是俚语--的集合。当你读或写P6代码时,你读或写的源代码是从一个俚语开始的,但有几个部分是用其他俚语写的。文件中的第一行使用主要俚语。假设这与英语类似。正则表是用另一种俚语写的;假设那就像西班牙语。因此,在语法String::Simple::grammar的情况下,代码以英语开始(USE V6;语句),然后递归为西班牙语(规则TOP{{之后),即^ $ 位,然后返回为英语(#Note...开始的注释)。然后,对于 {} )>$ ,它再次递归为西班牙语,在西班牙语中间的{}代码解锁处,它再次递归为另一级别的英语。这就是英语中的西班牙语中的英语。当然,代码块是空的,所以这就像在英语中什么都不写/读,然后立即返回到西班牙语中一样,但重要的是要理解这种递归的语言/运行时堆叠是P6的工作方式,无论是作为单一的整体语言/运行时,还是在与其他非P6语言/运行时合作时。

    5在应用两个潜在改进的过程中,我遇到了几个bug,如本脚注末尾所列。(BriandFoy的回答和这个都提到了。)两个“改进”是使用~构造,以及一个“not a quote”构造,而不是在foo>.之前使用<!。最后的结果,加上提到相关的bug:

    grammar String::Simple::Grammar {
      rule TOP {^ <string> $}
      token string {
        :my $*not-quote;
        <quote> ~ $<quote>
        [
          { $*not-quote = "<-[$<quote>]>" }
          <quotebody($<quote>)>
        ]
      }
      token quote { '"' | "'" }
      token quotebody($quote) { ( <escaped($quote)> | <$*not-quote> )* }
      token escaped($quote) { '\\' ( $quote | '\\' ) }
    }
    

    如果有人知道一个更简单的方法来做到这一点,我很想在下面的评论中听到它。

    最后,我在RT bugs数据库中搜索了所有的regex bug。我知道bug数据库不是这样,但我认为我应该注意以下几点。Aiui,前两个直接与匹配变量的发布问题交互。

    看起来有很多讨厌的线程错误。最主要的原因是一些regex特性在幕后使用eval,而eval还不是线程安全的。幸运的是,官方医生提到了这些。

    由于.parse设置$/无法执行递归语法。

    6这个问题和我的回答使我对P6一个雄心勃勃和复杂的方面的理解达到了外部极限。我计划很快深入了解nqp和完整P6之间的精确交互,以及它们的regex俚语和主要俚语之间的交接,正如上面脚注中所讨论的那样。(我目前的希望主要寄托在刚刚收购了Commaide。)如果/当我有一些结果时,我会更新这个答案。

  •  类似资料:
    • 打开和关闭连接: 注册用户 错误消息 '/'应用程序中的服务器错误。 INSERT INTO语句中存在语法错误。 描述:在执行当前Web请求期间发生未处理的异常。请查看堆栈跟踪以获取有关错误及其在代码中的起源的更多信息。 异常详细信息:系统。数据。OleDb。OleDbException:INSERT INTO语句中的语法错误。 源错误: 第100行:命令。ExecuteNonQuery();第1

    • 我刚刚开始探索perl6语法。如何创建一个标记“行”来匹配行首和行尾之间的所有内容?我尝试了以下方法,但没有成功:

    • 我正在尝试使用Perl6语法实现Markdown解析器,但被块引号卡住了。块引号段落不能用嵌套大括号表示,因为它是一个特定格式行的列表。但从语义上讲,它是一个嵌套的标记。 基本上可以归结为以下定义: mdBQLine令牌的实际实现与此无关。唯一需要注意的是,mdBQLineBody键包含实际引用的带有

    • 问题内容: 像 不再添加 问题答案: 更新(最终版2.0.0) 更新 将在RC.6中重命名为 原版的 Angular2 intruduced CSS值的消毒和财产样结合,并在RC.1 这些值可以通过使用标记为受信任 并绑定到该值,而不是不受信任的纯字符串。 这也可以包裹在类似 与 提示 无法使用已清理的内容,因为在分配值之前,stringyfies值会破坏清理。

    • 本文向大家介绍Powershell中Finally语句用法示例,包括了Powershell中Finally语句用法示例的使用技巧和注意事项,需要的朋友参考一下 在之前的小技巧中,我们曾经引入过,一个有声的进度条。在PowerShell正在做某项忙碌的任务时,可以一直让它播放某段音乐。代码如下: 脚本本来运行正常,但是当你终止了它,比如使用ctrl+C来终止,此时脚本运行立马结束。最后一行的$pla