Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Grammar 我可以在匹配树中插入命名捕获而不实际匹配任何内容吗?_Grammar_Raku - Fatal编程技术网

Grammar 我可以在匹配树中插入命名捕获而不实际匹配任何内容吗?

Grammar 我可以在匹配树中插入命名捕获而不实际匹配任何内容吗?,grammar,raku,Grammar,Raku,我很好奇我是否可以在没有任何东西的情况下将东西插入到匹配树中。我不想解决任何相关的问题 在本例中,我有一个令牌market,用于检查其匹配项是否是散列中的密钥。然后我试图以某种方式将该散列的值插入到匹配树中。我想我可以有一个始终匹配的令牌,long\u market\u string,然后以某种方式查看树,看看market匹配了什么 grammar OrderNumber::Grammar { token TOP { <channel> <prod

我很好奇我是否可以在没有任何东西的情况下将东西插入到匹配树中。我不想解决任何相关的问题

在本例中,我有一个令牌
market
,用于检查其匹配项是否是散列中的密钥。然后我试图以某种方式将该散列的值插入到匹配树中。我想我可以有一个始终匹配的令牌,
long\u market\u string
,然后以某种方式查看树,看看
market
匹配了什么

grammar OrderNumber::Grammar {
    token TOP    {
        <channel> <product> <market> <long_market_string> '/' <revision>
        }

    token channel    { <[ M F P ]> }
    token product    { <[ 0..9 A..Z ]> ** 4 }

    token market     {
        (<[ A..Z ]>** 1..2) <?{ %Market_Shortcode{$0}:exists }>
        }

    # this should figure out what market matched
    # I don't particularly care how this happens as long as
    # I can insert this into the match tree
    token long_market_string { <?> }

    token revision   { <[ A..C ]> }
    }

但是,这就解决了这个问题。我更感兴趣的是插入任意数量的东西。

令牌是一种方法,因此,如果您编写了一个方法来完成令牌为您所做的所有设置工作,那么您几乎可以做任何事情

这不具体,目前也不容易。
(我只是模糊地知道从哪里开始查找源代码来找出答案)


您可以轻松地添加到结果的
.made
/
.ast
.made
.ast
是同义词)

$/=语法{
令牌顶部{
.*
{
打造“世界”
}
}
}.parse('Hello');
说“$/$/.made()”;#你好,世界
它甚至不必在语法中

'asdf'~~/{make 42}/;
说$/;「
比如说$/.made#42

大多数情况下,您都会使用Actions类来处理这类事情

语法示例语法{
令牌顶部{
[|]+%\s*
}
象征词{
+
}
令牌号{
\d+
{make+$/}
}
}
集体示范行动{
方法TOP($/){make$/.pairs.map:{.key=>.value».make}
方法编号($/){#`(已在语法中完成,因此可以删除)}
方法词($/){make~$/}
}
。比如说-grammar.parse(
“你好123世界”,
:操作(示例操作)
).made».perl
#:编号([123])
#:word([“你好”,“世界”])

听起来你想颠覆匹配树,让它做一些匹配树实际上不应该做的事情。匹配树跟踪输入字符串中匹配的子字符串,而不是解析器生成的任意数据。如果要跟踪任意数据,AST树有什么问题

当然,在某种意义上,AST树必须镜像解析树,因为它是在匹配方法成功完成时以自底向上的方式构建的。但是AST本身,在“连接到任何给定节点的对象”的意义上,并没有这样的限制。例如,考虑:

grammar G {
    token TOP { <foo> <bar> {make "TOP is: " ~ $<foo> ~ $<bar>} }
    token foo { foo {make "foo"} }
    token bar { bar {make "bar"} }
}
G.parse("foobar");
$.ast
现在将是“双A”。当然,我可能会省去
令牌long\u market\u name
,而只做
令牌market
中的任何东西的AST(或者,如果您想同时跟踪这两个名称,可以使用短名称和长名称的market对象)

这类事情的一个不那么简单的例子是类似Python语法的东西。由于Python的块级结构是基于行的,所以语法(以及匹配树)需要以某种方式反映这一点。但是,您也可以通过使用分号将几个简单语句分隔开,将它们链接在一行上。现在,您可能希望块的AST是语句列表,而单行的AST本身可能是多个语句的列表。因此,您可以通过(例如)
flatmap
将行列表(或沿着这些行的东西,取决于您如何表示块语句,如
if
while
)组合在一起来构造块的AST


现在,如果你真的,真的,真的想对火柴树做一些讨厌的事情,我很确定这是可以做到的,当然。您必须使用
方法long\u market\u name
自己实现解析代码,该API是未记录的内部API,并且可能至少会涉及到nqp::ops中的一些下拉列表。指出的东西可能会有用。其他相关文件是Rakudo repo中的
src/core/{Match,Cursor}.pm
。还要注意的是,匹配的字符串化是通过从输入字符串中提取匹配的子字符串来计算的,因此,如果您想让它有效地字符串化,就必须对Match进行子类化。

这与我的要求并不接近,真的。所有这些都很容易。我想在匹配树中插入其他没有令牌的东西。您不能“几乎做任何事情”,因为匹配对象具有不可变位。@briandfoy Int也是不可变对象。当我说令牌是一种方法时,我的意思是它继承了方法,并添加了一些东西。如果你自己用一种常规的方法来做这些事情,你完全可以做一个代币所能做的一切。我不打算花一周或更长的时间来研究源代码来做一些几乎没有人需要做的事情。在你问我之前,我已经试过做同样的事情好几次了,在花了几个小时之后,我觉得不值得花时间。好吧,但我已经知道了,并且没有对此进行辩论。你说你也尝试过同样的事情(我猜这意味着你做不到),但听起来你也在试图说服我,靠我一个人去做是件小事。混合信息。@briandfoy我还有其他兴趣要研究,这对我当时来说更有趣,也更容易做。AST树是我试图颠覆的。但是,确实没有AST。有一个匹配对象树,其中包含一个名为“ast”的键,该键没有直接连接。AST被强制与匹配树具有相同的结构。“AST被强制与匹配树具有相同的结构”嗯?AST存在于匹配对象中。AST存在于匹配对象中,但如果您需要插入不匹配的内容,则没有任何东西可以阻止您生成生成AST的空匹配(如上面的
令牌长\u市场\u字符串中所示)。匹配树的目的是跟踪哪些规则匹配了哪些地方;跟踪
grammar G {
    token TOP { <foo> <bar> {make "TOP is: " ~ $<foo> ~ $<bar>} }
    token foo { foo {make "foo"} }
    token bar { bar {make "bar"} }
}
G.parse("foobar");
grammar G {
    my %Market_Shortcode = :AA('Double A');
    token TOP    {
        <channel> <product> <market>
        {} # Force the computation of the $/ object. Note that this will also terminate LTM here.
        <long_market_string(~$<market>)> '/' <revision>
        }

    token channel    { <[ M F P ]> }
    token product    { <[ 0..9 A..Z ]> ** 4 }

    token market     {
        (<[ A..Z ]>** 1..2) <?{ %Market_Shortcode{$0}:exists }>
        }

    token long_market_string($shortcode) { <?> { say 'c='~$shortcode; make %Market_Shortcode{$shortcode} } }

    token revision   { <[ A..C ]> }
    }

G.parse('M0000AA/A');