【问题标题】:How can I write an alias of Raku regexes?如何编写 Raku 正则表达式的别名?
【发布时间】:2020-07-15 11:56:38
【问题描述】:

我写了一个这样的语法:

grammar StatementFormat {
    token TOP { (<plain> | '%' <placeholder>)* }

    token plain { <-[%]> }

    token placeholder {
        | <verb>
        | <noun>
        | <adverb>
    }

    token verb {
        'v'
        {
            # some actions
        }
    }

    token noun {
        'n'
        {
            # some actions
        }
    }

    token adverb {
        'a'
        {
            # some actions
        }
    }
}

所以我可以用它来解析像“someone %v %n %a”这样的字符串。

但是,我发现有很多用法,比如“%v %n %a”,我想给它一个别名,比如“%b”,这样解析“someone %b”就相当于解析“某人 %v %n %a”。

那么有没有办法做到这一点?

当然,token alias { 'b' { ... } } 可以做到这一点。但是这样我需要重复那个动作代码。我想知道是否存在更简单的方法。

【问题讨论】:

    标签: alias grammar raku


    【解决方案1】:

    所以,有一种显而易见的方法,就是简单地将动作代码放入子例程中,然后在 b 别名中调用它们:

    sub verb-action($/) { }
    sub noun-action($/) { }
    sub adverb-action($/) { }
    
    grammar StatementFormat {
        # rest goes here
    
        token verb {
            'v'
            { verb-action($/) }
        }
    
        token noun {
            'n'
            { noun-action($/) }
        }
    
        token adverb {
            'a'
            { adverb-action($/) }
        }
    
        token alias {
            'b'
            {
                verb-action($/);
                noun-action($/);
                adverb-action($/);
            }
        }
    }
    

    但那有什么乐趣呢?

    相反,我建议使用内置的action object feature of grammars

    它是这样的:你有一个单独的类,其中动作作为方法,与语法动作同名:

    class StatementFormatActions {
        method verb($/) { ... }
        method noun($/) { ... }
        method adverb($/) { ... }
    
    }
    

    当您调用parse 时,您会传递该操作类的一个实例:

    StatementFormat.parse($string, :actions(StatementFormatActions.new));
    

    那么在引入alias令牌时,也可以引入alias方法:

    method alias($/) {
        self.verb($/);
        self.noun($/);
        self.adverb($/);
    }
    

    在操作中,您还可以调用 make$/.make(...) 将操作结果附加到匹配对象(然后在$/.made 中可用),以从解析树中填充 AST。

    (您可能还喜欢my book on grammars,它有几个例子和更深入的解释。抱歉插件,无法抗拒)。

    【讨论】:

    • 谢谢,它有效。此外,我想知道是否可以在解析过程中修改字符串。如果我可以用%v %n %a 替换%b,那么实现别名就很容易了。但似乎 raku 不支持此功能。你觉得有用吗?
    • @lovetomato 字符串在 Raku 中是不可变的,因此您无法在解析时对其进行修改。
    猜你喜欢
    • 2020-03-24
    • 2018-06-10
    • 2020-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多