#token #indentation #tokenizer #tokenize

indent_tokenizer

基于缩进生成标记

4 个版本 (破坏性更新)

使用旧的 Rust 2015

0.4.0 2018 年 1 月 29 日
0.3.0 2018 年 1 月 28 日
0.2.0 2017 年 4 月 22 日
0.1.0 2017 年 4 月 17 日

#9 in #indentation

GPL-3.0 许可证

56KB
1K SLoC

缩进标记器

一个小巧简单的缩进标记器

一个类似的项目是 indentation_flattener. 在这个例子中,我们通过添加 PUSH_INDENT 和 POP_INDENT 来平坦化输入。这对 PEG 语法来说看起来更好。

使用方法

添加到 cargo.toml [source, toml]

[dependencies]
indent_tokenizer = "0.2.0"

见下面的示例

修改

0.2.0:: 删除了通用类型(如 String、u32 或 usize)+ 使用具体类型(新类型)

缩进格式

制表符在缩进分组中无效。

让我们通过示例来了解。

简单有效输入

.....
...
    ....
        ....
        ....
    ....
    ....
....
....
    ....

缩进组可以包含任意数量的空格

有效缩进不同空格

.....               level0
  ....              level1  <--
        ....        level2
  ....              level1  <--
  ....              level1  <--
....                level0
....                level0
      ....          level1  <--

不同级别的相同缩进不是一个好主意,但在创建新级别时是允许的。

在这个例子中,最后一个级别1的缩进比前面的更多

无效缩进

.....
...
    ....
        ....
       ....     <--  incorrect indentation
    ....        <--  correct previous ident level
    ....
....
....
    ....

为了回到一个级别,缩进必须与该级别上之前的缩进匹配。

如前一个示例所示,增加级别是自由缩进。

起始行指示符

|.....
    |.....
    |......
        |......

你可以用 | 开始行,但这不是必需的。

缩进指示符是可选的

.....
    |.....
     ......
     ......
        ......

注意 | 在缩进级别之前一个位置。

当需要以空格开始时,这很有用。

我想用空格开始一行

.....
    | .....     <- This line starts with an space
    |  ......   <- Starting with 2 spaces
    |.....      <- starts with no spaces
     .....      <- starting with no spaces
     ...        <- starting with no spaces

我的行以 | 开始

.....
    ||.....     This line starts with a `|`
    |......     This one starts with `.`

如果一行没有内容或只有空格,则该行是空的。

空行

.....
    .....
    .....
    .....
    .....     next line is empty

    .....     next line is empty

.....
.....         next line is empty

如果我想要表示空行怎么办?

表示空行

.....
    .....
    .....
    .....
    .....     I want new line after this line
   |

    .....     and three new lines, please
   |
   |
   |

如果我想要表示行尾的空格怎么办?

行尾的空格不会被删除,因此,你不需要为此做任何事情。

但是,可以有趣地表示它,因为一些编辑器可以运行尾随空格,或者只是因为它可以可视化。

表示行尾空格

.....
    .....
    .....
    .....
    This line keeps 2 spaces and end  |
    and you know it

    Next line is properly indented and only has spaces
   |   |

实际上,你可以在所有行的末尾写 |。它将被删除。

以下字符串是等价的。

行尾的 | 是可选的

.....|
    .....|
    .....|
    .....|


.....
    .....
    .....
    .....

但我可能需要在行尾有一个管道 |

行尾的管道

.....
    .....
    .....
    .....
    This line ends with a pipe||

陷阱

|.....
.....   <- Invalid, remember, indentation mark | is previus to real indentation


|.....
 .....   <- This is OK, but not elegant


| ....   <- I want to start with an space
|.....   <- This is redundant, but more clear
 

标记

  • 级别的每次变化都表示标记的结束。
  • 空行用于在相同级别上分隔标记
  • 标记包含行和标记列表

令牌

This is the first token
    This is another token, because it's on a different level
        And another token
    This is also a different token

A token can contain
multiple lines
    This is another token
    with three
    lines

Empty lines can be used to
separate tokens
    This is a token,
    that continues
    here. Next empty line define
    a token division

    And this is a different one
    with a couple of lines

缩进令牌化API

版本0.2删除了通用类型,如String、usize、u32等...

相反,它为每个上下文创建了一个特定的类型。

具体类型:[source, rust]

#[derive(Debug, PartialEq, Copy, Clone)]
pub struct LineNum(u32);

#[derive(Debug, PartialEq, Clone, Eq)]
pub struct SLine(String);
  • LineNum表示行号
  • SLine表示行字符串

内部,系统使用更多的新类型,如NSpaces表示空格数

要调用的函数:[source, rust]

pub fn tokenize(input: &str) -> Result<Vec<Token>, Error> 

令牌类型:[source, rust]

#[derive(Debug, PartialEq)]
pub struct Token {
    pub lines: Vec<SLine>,
    pub tokens: Vec<Token>,
}

错误类型:[source, rust]

#[derive(Debug, PartialEq)]
pub struct Error {
    pub line: LineNum,
    pub desc: String,
}

就这些

查看lib.rs以了解API,查看tests.rs以查看示例

示例

您可以查看tests.rs,其中包含几个测试。

.复杂示例 [source, rust]

    let tokens = tokenize("
0
    || 01a
     01b
     01c

     02a
     02b

        |020a
        ||020b

        |  021a
        |021b
1a
1b
    11a
   ||11b
    11c

    12a  ||
   |12b  ||
2a
    21a
    21b
   |
   |

")

结果将是

[source, rust]

   vec![Token {
            lines: vec![SLine::from("0")],
            tokens: vec![Token {
                            lines: vec![SLine::from("| 01a"),
                                        SLine::from("01b"),
                                        SLine::from("01c")],
                            tokens: vec![],
                        },
                        Token {
                            lines: vec![SLine::from("02a"), SLine::from("02b")],
                            tokens: vec![Token {
                                            lines: vec![SLine::from("020a"),
                                                        SLine::from("|020b")],
                                            tokens: vec![],
                                        },
                                        Token {
                                            lines: vec![SLine::from("  021a"),
                                                        SLine::from("021b")],
                                            tokens: vec![],
                                        }],
                        }],
        },
        Token {
            lines: vec![SLine::from("1a"), SLine::from("1b")],
            tokens: vec![Token {
                            lines: vec![SLine::from("11a"),
                                        SLine::from("|11b"),
                                        SLine::from("11c")],
                            tokens: vec![],
                        },
                        Token {
                            lines: vec![SLine::from("12a  |"), SLine::from("12b  |")],
                            tokens: vec![],
                        }],
        },
        Token {
            lines: vec![SLine::from("2a")],
            tokens: vec![Token {
                            lines: vec![SLine::from("21a"),
                                        SLine::from("21b"),
                                        SLine::from(""),
                                        SLine::from("")],
                            tokens: vec![],
                        }],
        }];

无运行时依赖项