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

在Perl 6中传递数据以形成语法规则

茹展鹏
2023-03-14

不确定语法是否要做这样的事情:我希望在运行时定义标记(将来使用文件中的数据)。所以我编写了一个简单的测试代码,正如预期的那样,它甚至不会编译

grammar Verb {
  token TOP {
    <root> 
    <ending>
  }
  token root {
    (\w+) <?{ ~$0 (elem) @root }>
  }
  token ending {
    (\w+) <?{ ~$0 (elem) @ending }>
  }
}

my @root = <go jump play>;
my @ending = <ing es s ed>;

my $string = "going";
my $match = Verb.parse($string);
.Str.say for $match<root>;

在Perl 6中执行此类操作的最佳方法是什么?

共有2个答案

徐凌
2023-03-14

你采取的方法本可以奏效,但你犯了三个错误。

编译器使用词法变量声明之前,需要以文本形式显示它们:

my $foo = 42; say $foo; # works
say $bar; my $bar = 42; # compile time error
say .parse: 'going' for

  grammar using-token              {token TOP {         \w+ ing}}, # Nil
  grammar using-regex-with-ratchet {regex TOP {:ratchet \w+ ing}}, # Nil
  grammar using-regex              {regex TOP {         \w+ ing}}; # 「going」

regex声明符与token声明符的效果完全相同,只是它默认执行回溯。

您在root令牌中第一次使用\w匹配整个输入'go',然后无法匹配@root的任何元素。然后,因为没有回溯,整个解析立即失败。

(不要认为这意味着您应该默认使用regex。依赖回溯会大大减慢解析速度,通常不需要它。)

看见https://stackoverflow.com/a/19640657/1077672

这项工作:

my @root = <go jump play>;
my @ending = <ing es s ed>;

grammar Verb {
  token TOP {
    <root> 
    <ending>
  }
  regex root {
    (\w+) <?{ ~$0 (elem) @root }>
  }
  token ending {
    (\w+) <?{ ~$0 (elem) @ending }>
  }
}

my $string = "going";
my $match = Verb.parse($string);

.Str.say for $match<root>;

输出:

go
郎曜文
2023-03-14

要匹配数组的任何元素,只需在正则表达式中写入数组变量的名称(以sigil开头):

my @root = <go jump play>;
say "jumping" ~~ / @root /;        # Matches 「jump」
say "jumping" ~~ / @root 'ing' /;  # Matches 「jumping」

因此,在您的用例中,唯一棘手的部分是将数组从创建它们的代码(例如通过解析数据文件)传递给需要它们的语法标记。

最简单的方法可能是使其成为动态变量(由twigil表示):

grammar Verb {
    token TOP {
        <root> 
        <ending>
    }
    token root {
        @*root
    }
    token ending {
        @*ending
    }
}

my @*root = <go jump play>;
my @*ending = <ing es s ed>;

my $string = "going";
my $match = Verb.parse($string);

say $match<root>.Str;

另一种方法是将带有数组的捕获传递给方法副词。解析(parse),这将把它们传递到令牌TOP,然后您可以使用

grammar Verb {
    token TOP (@known-roots, @known-endings) {
        <root: @known-roots>
        <ending: @known-endings>
    }
    token root (@known) {
        @known
    }
    token ending (@known) {
        @known
    }
}

my @root = <go jump play>;
my @ending = <ing es s ed>;

my $string = "going";
my $match = Verb.parse($string, args => \(@root, @ending));

say $match<root>.Str;  # go

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

  • 如果我执行以下代码 我得到以下输出: 但是我不明白,如果我使用UInt-或Int-数组,为什么会有所不同。这可能是一个错误吗? 我正在使用基于MoarVM版本2016.12构建的Rakudo版本2016.12(包含在Debian拉伸中)

  • 我有一些RadioButton在片段A,,和一些RadioButton在片段B我希望当这些(FragmentA)之一,在FragmentB禁用所有单选按钮.相同的活动主机这些片段。 片段A中的事件单击单选按钮:

  • 问题内容: 我一直在寻找答案,但只能找到答案。 我有一个按钮可以选择。没有代码,我通过“接口”构建器进行设置。上,我有一个按钮,可以自行关闭 我想从视图传递回时传递一个字符串。我该怎么做呢?另外,我正在使用swift。 提前致谢! 问题答案: 有两种常见的模式,这两种模式都消除了viewController2明确了解viewController1的需要(这对于可维护性非常重要): 为您的viewC

  • 问题内容: Mockito似乎是一个非常漂亮的Java存根/模拟框架。唯一的问题是,我找不到有关使用其API的最佳方法的任何具体文档。测试中常用的方法包括: 在实践中看到Mockito的示例时,您将看到类似以下的代码: 从我阅读的所有文档中,我已经确定了通过菊花链将这些方法调用链接在一起而获得的Mockito“语法”的几种“模式”,就像上面的示例一样。我发现的一些常见模式是: 什么时候/然后: w

  • 我一直挣扎在这甚至在做了这么多的研究这么简单的事情,所以我需要一些帮助在这里。 我需要传递日期数据类型的当前日期,只有'yyyy-mm-dd'格式。SimpleDateFormat将当前日期转换为字符串类型,在尝试解析时,它将转换为日期类型,但会更改格式。 我需要日期类型的“YYYY-MM-DD”格式的currentDate。