12 个版本 (3 个稳定版)
1.0.2 | 2023 年 3 月 13 日 |
---|---|
1.0.0 | 2023 年 2 月 28 日 |
0.9.6 | 2023 年 2 月 28 日 |
0.8.1 | 2023 年 2 月 7 日 |
0.8.0 | 2023 年 1 月 31 日 |
#1515 in 命令行工具
95KB
1.5K SLoC
Phonet
Phonet 是一个用于验证构建语言音位学模式的 CLI 工具和库。它兼容罗马化和音标转录。可以随机生成单词(参见 参数语法)。
用法
此项目可以作为 rust 库 crate 或二进制可执行文件使用。
二进制使用
参数语法
由 Clap 生成
Usage: phonet.exe [OPTIONS] [TESTS]...
Arguments:
[TESTS]...
Custom tests (optional)
This overrides all tests in the file
Options:
-f, --file <FILE>
Name and path of file to run and test
If name ends with a period, the 'phonet' extension is implied
Eg. `phonet -f myfile.phonet` or `phonet -f myfile.` (same result)
If name ends with a slash, the '/phonet' file name is implied
Eg. `phonet -f folder/phonet` or `phonet -f folder/` (same result)
[default: phonet]
-q, --quiet
Don't display passes and notes, only fails
-m, --minify
Minify file and save
-w, --with-tests
Include tests in minified file
-g, --generate [<GENERATE>]
Generate random words
Default count 1, specify with number
--gmin <GENERATE_MIN_LEN>
Set minimum length (inclusive) for generated words
Use with the `--generate` or `-g` flag
Note: This increases generation time exponentially
[default: 3]
--gmax <GENERATE_MAX_LEN>
Set maximum length (inclusive) for generated words
Use with the `--generate` or `-g` flag
[default: 20]
-n, --no-color
Display output in default color
Use for piping standard output to a file
-h, --help
Print help (see a summary with '-h')
-V, --version
Print version
示例
# Runs ./phonet
phonet
# Runs ./phonet, with tests: 'some', 'tests' (overrides the tests in file)
phonet some tests
# Runs ./myfile.phonet
phonet -f myfile.phonet
phonet -f myfile.phonet some tests
# 'phonet' extension implied
phonet -f myfile.
# 'phonet' filename implied
phonet -f src/phonet
phonet -f src/
# Runs ./phonet, only showing fails
phonet -q
# Runs ./phonet, and minifies to ./min.phonet without tests
phonet -m
# Runs ./myfile.phonet, only displaying fails, and minifies to ./myfile.min.phonet with tests
phonet -f myfile. -q -mw
# Runs ./phonet, and generates 1 random word
phonet -g
# Runs ./myfile.phonet, and generates 10 random words
phonet -g10 -f myfile.phonet
# Runs ./phonet, with no color, and writes output to ./phonet.txt
phonet -n > phonet.txt
# Runs ./myfile.phonet, only displaying fails, and generates 3 random words with length 6-8, writes output to ./phonet.txt (with no color)
phonet -f myfile. -qn -g 3 --gmin 6 --gmax 8 > ./phonet.txt
创建别名/路径
将 <path_to_file>
替换为下载的二进制文件的目录。
Bash
在用户目录下的 .bashrc
中添加别名
# ~/.bashrc
alias phonet="<path_to_file>/phonet.exe"
Powershell
添加到 $env:PATH
$env:Path = "$env:Path;<path_to_file>\phonet.exe"
库使用
将 phonet = "1.0.2"
添加到您的 Crates.toml
文件
简例
use phonet::Draft;
fn main() {
let file = std::fs::read_to_string("phonet").unwrap();
// Parse draft
Draft::from(&file).unwrap()
// Run tests
.run()
// Display results
.display(Default::default(), true)
}
长例
use std::fs;
use phonet::{
draft::{Message::Test, TestDraft},
get_min_filename, DisplayLevel, Draft,
};
fn main() {
let filename = "myfile.phonet";
// Read file
let file = fs::read_to_string(filename).expect("Could not read phonet file");
// Parse file
let mut draft = Draft::from(&file).expect("Failed to parse file");
// Add a custom test
draft.messages.push(Test(TestDraft {
intent: true,
word: "taso".to_string(),
}));
// Minify file
fs::write(
get_min_filename(filename),
draft.minify(false).expect("Failed to minify"),
)
.expect("Could not write minified file");
// Run tests and display only failed tests
draft.run().display(DisplayLevel::OnlyFails, true);
// Create a generator for random words
// Each with a length between 5 and 8 (inclusive)
// Generation is done lazily, similar to an iterator
println!("Randomly generated words:");
let mut words = draft
.generator(5..=8)
.expect("Failed to create word generator");
// Generate 10 random words
for _ in 0..10 {
println!(" - {}", words.next());
}
}
文件语法
一个 Phonet 文件用于定义程序的规则、类和测试。
该文件应命名为 phonet
,或以 .phonet
结尾。
语句
语法是语句,每个语句由分号 ;
或换行符分隔。
使用 Ampersand &
表示多行语句。这只能用分号 ;
结束。注意,注释不能多行。
注释将以换行符或分号 ;
结尾
所有空白都将被忽略,除了在 测试 中分隔单词。
注意!这将在正则表达式中也替换空格!如果您需要空格,请使用
\s
每个语句必须以操作符开头
#
Hashtag:整行注释。换行符(不是分号)结束注释$
美元符号:定义一个类+
加号 或!
感叹号:定义一个规则*
星号:创建一个测试注释,并在测试失败时定义一个原因?
问号:创建一个测试~
波浪号:定义文件的模式
类
类用作简写正则表达式,在运行时被替换到规则中。
注意:尖括号将不会直接解析为类名
- 一个开括号和一个问号:
(?
- 一个开括号、问号和字母 'P':
(?P
- 一个反斜杠和字母 'k':
\k
这是用于后视和命名组的语法
语法
$
美元符号- 名称 - 只能是 [a-zA-Z0-9_] 中的字符
=
等于- 值 - 正则表达式,可能包含尖括号
<>
或⟨⟩
中的其他类(与规则相同)
名为 'any' 的类,用 $_ = ...
定义,用于随机单词生成。
示例
# Some consonants
$C = [ptksmn]
# Some vowels
$V = [iueoa]
# Only sibilant consonants
$C_s = [sz]
# Every letter
$_ = ⟨C⟩ | <V>
规则
规则是用于测试单词是否有效的正则表达式。
规则用意图定义,可以是+
(表示正)或!
(表示负)。
- 正则必须遵循,单词才有效
- 负则必须不遵循,单词才有效
要使用类,使用类名,并用尖括号 <>
或 ⟨⟩
包围
语法
+
加号 或!
感叹号 - 加号用于正则,感叹号用于负则- 模式 - 正则表达式,可能包含尖括号
<>
或⟨⟩
中的类
示例(带有预定义类)
# Must be (C)V syllable structure
+ ^ (<C>? ⟨V⟩)+ $
# Must not have two vowels in a row
! <V>{2}
测试
测试将与所有规则进行比较,并在输出中显示结果。
测试将按照定义的顺序运行。
与规则一样,测试必须有一个定义的意图,即+
(表示正)或!
(表示负)。
- 正测试在有效时将通过
- 负测试在有效时将失败
语法
?
问号+
加号 或!
感叹号 - 加号用于正测试,感叹号用于负测试- 测试 - 一个单词,或由空格分隔的多个单词
示例(包含预定义的规则)
# This should match, to pass
?+ taso
# This test should NOT match, to pass
?! tax
# Each word is a test, all should match to pass
?+ taso sato tasa
备注
备注将被打印到终端输出,与测试并行。
它们用作任何后续规则的原因,如果测试失败,则作为解释。
语法
*
星号:
冒号 (可选) - 定义一个 '安静' 备注- 要打印的文本,以及定义原因
示例
* Syllable structure
+ ^ (<C>? <V>)+ $
# This test will NOT match, however it SHOULD (due to the Plus), so it will FAIL, with the above note as the reason
?+ tasto
# This is a 'quiet' note, it will not display, but it will be used as the reason for the following rule
*: Must not have two vowels in a row
! <V>{2}
?+ taso
模式
Phonet 文件的模式可能是以下之一
- 罗马化:使用
<>
(不是⟨⟩
) - 宽式转录:使用
//
- 窄式转录:使用
[]
这可以作为一个文件中的可选指定,尽管它不会添加任何功能。
语法
~
波浪号<.>
,/./
或[.]
- 模式标识符,其中.
是任何字符串或空白
示例
# Specify romanized mode (fish icon)
~<>
# Specify broad transcription, with a given name
~ / My Language /
示例
请参阅示例文件夹中的Phonet文件示例。
推荐的语法模式
这些格式化提示不是必需的,但建议使用,以便使文件更容易阅读。
- 在文件最顶部指定模式
- 在文件顶部定义所有类
- 首先定义一个'any' 类,用于单词生成
- 使用备注分组相关规则和测试
- 首先定义规则,然后是正测试,然后是负测试
- 在备注下缩进规则和测试
- 规则应使用 1 个意图,测试使用 2 个
示例文件
示例(这来自example.phonet)
~<> ;# Mode (optional) - This file uses romanized letters
# Class definitions
$_ = ⟨C⟩ | ⟨V⟩ ;# Any / all letters (required for generating words)
$C = [ptkmnswjl] ;# Consonants
$V = [aeiou] ;# Vowels
* Invalid letters ;# Note - Prints to standard output, and used as reason if test fails
+ ^ ⟨_⟩+ $ ;# Check that every letter is in the 'any' class
?+ taso
?! tyxo
* Examples of failing tests
?+ tyxo ;# This test will fail - with the reason 'Invalid Letters' (above)
?! taso ;# This test will fail, as a false positive
* Syllable structure
+ ^ ⟨V⟩? ( ⟨C⟩ ⟨V⟩ )+ $ ;# Check that word is Consonant + Vowel, repeating at least once
?+ taso kili ano atoso
?! taaso an
* Some more tests
?+ silo tila
?! akka axe
# This is a 'quiet' note - It will not display, unless any following rules fail
*: No repeated letters
! (.)\1 ;# This is an unnamed back-reference
! (?<x> .) \k<x> ;# (Alternative) This is a named back-reference (NOT a class)
?+ taso ;# An example of multi-line statements on next line (comments cannot be on same line)
?! &
taaso
ttaso
;
# Comments cannot be multiline, even using '&'
* 2 tests *should* have failed!
依赖项
~4.5–6.5MB
~113K SLoC