//! ONA方言语法
//! * 🎯从ONA输出中解析Narsese
//! * 📌复合词项的「中缀形式」「空格分隔」形式
//! * 📄以空格分隔的词项:`(* {SELF})`
//! * 📄`({SELF} * x)`
/// 空白符 | 所有Unicode空白符,解析前忽略
WHITESPACE = _{ WHITE_SPACE }
/// 总入口:词法Narsese | 优先级:任务 > 语句 > 词项
narsese = _{
task
| sentence
| term
}
/// 任务:有预算的语句
task = {
budget ~ sentence
}
/// 预算值 | 不包括「空字串」隐含的「空预算」
budget = {
"$" ~ budget_content ~ "$"
}
/// 预算值内容
budget_content = _{
(truth_budget_term ~ (";" ~ truth_budget_term)* ~ ";"*)
| "" // 空预算(但带括号)
}
/// 通用于真值、预算值的项 | 用作内部数值,不约束取值范围
truth_budget_term = @{ (ASCII_DIGIT | ".")+ }
/// 语句 = 词项 标点 时间戳? 真值?
sentence = {
term ~ punctuation ~ stamp? ~ truth?
}
/// 词项 = 陈述 | 复合 | 原子
term = _{
statement
| compound
| atom
}
/// 陈述 = <词项 系词 词项> | 非**原子规则**,强制其内表达式忽略空格
statement = !{
"<" ~ term ~ copula ~ term ~ ">"
}
/// 陈述系词
copula = @{
(punct_sym ~ "-" ~ punct_sym) // 继承/相似/实例/属性/实例属性
| (punct_sym ~ "=" ~ punct_sym) // 蕴含/等价
| ("=" ~ punct_sym ~ ">") // 时序性蕴含
| ("<" ~ punct_sym ~ ">") // 时序性等价
}
/// 标点符号 | 用于「原子词项前缀」「复合词项连接词」和「陈述系词」
punct_sym = { (PUNCTUATION | SYMBOL) }
/// 复合 = (连接词, 词项...) | {外延集...} | [内涵集...]
/// * 🆕对ONA兼容形如`(^op, {SELF}, LEFT)`的输出语法
/// * 🚩此处不进行「静默内联」:便于在「折叠函数」中向下分派
/// * 📝使用前缀「$」停止忽略空格,以使用「可选分隔符」
/// TODO: 【2024-04-03 11:50:06】对「像」可能需要特别的语法
/// * 📄`[OUT] Derived: <{SELF} --> (^left /1 P)>. :|: occurrenceTime=21 Priority=0.301667 Truth: frequency=1.000000, confidence=0.810000`
/// * 📄`[OUT] Derived: <P --> (^left /2 {SELF})>. :|`
compound = !{
compound_common
| compound_binary
| ext_set
| int_set
}
/// 通用的复合词项
compound_common = ${ "(" ~ connecter ~ optional_separator ~ term_list ~ ")" }
/// 通用的「词项列表」 | 静默展开
term_list = _{ term ~ (optional_separator ~ term)* }
/// 可选的分隔符
optional_separator = _{
("," ~ WHITESPACE*)
| WHITESPACE+
}
/// 🆕ONA特定的「二元中缀表达法」
/// * 🚩【2024-03-29 09:40:38】目前通用成`(A, B, C)` => `<(*, B, C) --> A>`的转换方式
compound_binary = { "(" ~ term ~ connecter ~ term ~ ")" }
/// 外延集 | 📌【2024-03-29 09:39:39】pest代码折叠中会丢掉所有「不被规则捕获的字符串信息」
ext_set = { "{" ~ term_list ~ "}" }
/// 内涵集
int_set = { "[" ~ term_list ~ "]" }
/// 复合词项连接词 | ⚠️不包括「逗号」与「圆括号」
connecter = @{ (!"," ~ !"(" ~ !")" ~ punct_sym)* }
/// 原子 = 前缀(可选) 内容
atom = {
placeholder // 占位符
| (atom_prefix ~ atom_content) // 变量/间隔/操作……
| atom_content // 词语
}
/// 占位符 = 纯下划线字符串
placeholder = @{ "_"+ }
/// 原子词项前缀
atom_prefix = @{ punct_sym+ }
/// 原子词项内容 | 已避免与「复合词项系词」相冲突
atom_content = @{ atom_char ~ (!copula ~ atom_char)* }
/// 能作为「原子词项内容」的字符
atom_char = { LETTER | NUMBER | "_" | "-" }
/// 标点
punctuation = { (PUNCTUATION | SYMBOL) }
/// 时间戳 | 空时间戳会直接在「语句」中缺省
stamp = {
":" ~ (!":" ~ ANY)+ ~ ":"
}
/// 真值 | 空真值会直接在「语句」中缺省
truth = {
"%" ~ (truth_budget_term ~ (";" ~ truth_budget_term)* ~ ";"*) ~ "%"
}