#lexer #generator #dfa #proc-macro #tokenizer #lex #macro-derive

luther-derive

Luther解析生成器的proc宏生成器

1 个不稳定版本

使用旧的Rust 2015

0.1.0 2018年5月28日

#22#lex

Apache-2.0/MIT

47KB
808

Luther derive

Luther是一个为稳定Rust设计的嵌入式词法分析器生成器。

此crate是用于从Luther crate派生Lexer特质的proc宏实现。有关proc宏所识别的选项,请参阅crate级别的文档。有关此crate的使用示例,请参阅Luther crate。

许可

Luther许可协议为以下之一

任选其一。

贡献

除非您明确声明,否则您向Luther提交的任何有意包含在内的贡献,根据Apache-2.0许可证定义,应按照上述方式双重许可,不附加任何额外的条款或条件。


lib.rs:

luther_derive提供了一个用于派生luther::Lexer特质的proc宏。

派生luther::Lexer特质是实现此特质的主要(可能是唯一)方式。该特质可以在具有正则表达式注解的token类型枚举上派生,枚举的变体不需要全部注解正则表达式,但没有注解的变体将不会由luther_derive生成的词法分析器返回。

生成词法分析器时,会为词法分析器内部使用的确定有限自动机添加一个可见的类型名称。一旦有了卫生宏,就可以隐藏这个名称,但根据当前的程序宏实现,名称将是可见的。默认情况下,名称是通过在派生自 luther::Lexerenum 名称后添加后缀 Dfa 来形成的。这个默认值可以用 luther 属性的 dfa 选项来覆盖。

示例

extern crate luther;

#[macro_use]
extern crate luther_derive;

#[derive(Lexer)]
enum Token {
    #[luther(regex = "ab")]
    Ab,

    #[luther(regex = "acc*")]
    Acc(String),
}

捕获识别的字符。

如果一个 enum 的变体,该变体在生成词法分析器时只包含一个类型(如上述示例中的 Acc 变体)并且该类型实现了 str::FromStr(如 StringAcc 示例的实现)那么当匹配到该变体的正则表达式时,生成的词法分析器将捕获识别的字符。它将通过使用该类型的 str::FromStr 实现来捕获字符。

在一个 enum 变体中包含多个类型是错误的。《code>luther_derive 将识别这个错误。同时,如果一个单独的类型没有实现 str::FromStr,这也是一个错误,但 luther_derive 无法识别这个错误。这种情况可能会以编译器输出的一个令人困惑的错误消息来表现。

目前,在枚举中包含的单个类型也必须实现 default::Default,尽管这种限制可能在将来被取消。

捕获字符的代码可能类似于 characters.parse().unwarp_or_default(),其中 characters 是识别的字符的 &str

luther 属性

luther_derive 识别了应用于 enum(为该 luther::Lexer 派生)及其变体的 luther 属性。《code>luther 支持各种选项,它们以 `#[luther(option = "value")]` 的形式调用。

luther 属性支持的选项如下,并指出了选项的有效位置(枚举或变体)

  • dfa:用于生成确定有限自动机的名称 [枚举]
  • regex:用于识别特定变体的正则表达式 [变体]
  • priority_group:变体所属的优先级组 [变体]

优先级组

多个 enum 变体的正则表达式可以匹配相同的输入。例如,以下正则表达式都匹配输入 "auto":

  1. "auto"
  2. "[a-z]+"
  3. "[a-z]+[0-9]*"

luther_derive 生成的词法分析器将优先考虑简单字符串作为 luther 属性上的 regex 选项,而不是更复杂的正则表达式。在上面的示例中,这意味着项目 1 将优先于项目 2 或 3。这条规则允许词法分析器优先考虑关键字而不是标识符,例如。

不过,如果对简单字符串的优先级不足以解决歧义,那么您将不得不使用 luther 属性的 priority_group 选项来指示其中哪一个(或多个)具有更高的优先级(较小的数字表示更高的优先级)。然而,在优先级组内部,luther_derive 仍将继续优先考虑简单字符串。

如果未指定,priority_group 的默认值为 1。

错误

luther_derive 将在以下情况下(以及其他情况)在编译时引发错误:

  • #[derive(Lexer)] 调用在一个 struct 而不是一个 enum
  • enum 的任何变体都没有指定 regex
  • 为变体指定的某个 regex 将匹配空字符串
  • 变体包含的类型不是 1 项的元组
  • regex 选项提供的值无法解析为正则表达式
  • priority_group 选项提供的值无法解析为整数

依赖

~2.5MB
~61K SLoC