脚本定义¶
总体说明¶
在该 DSL 中,脚本由以下三种结构的若干块组成:
CONFIG 块:用于配置全局设置,如大小写敏感与否。
VAR 声明:定义全局变量,可在后续的
RESPONSE文本中通过占位符${varName}引用。STATE 块:描述对话状态及其匹配规则(
RULE)和兜底规则(DEFAULT)。
脚本的整体外观示例:
CONFIG {
case_sensitive = false
}
VAR bankName = "XX银行"
STATE greeting {
RULE greetRule {
MATCH "你好"
RESPONSE "您好,这里是${bankName}智能客服,请问有什么可以帮您?"
GOTO askQuestion
}
DEFAULT {
RESPONSE "抱歉,我没有听清。您可以说'你好'来开始咨询。"
}
}
STATE askQuestion {
RULE loan {
MATCH "贷款"
RESPONSE "好的,您想了解哪方面的贷款业务呢?"
GOTO loanState
}
DEFAULT {
RESPONSE "如果想咨询贷款业务,请说'贷款';如果咨询信用卡,请说'信用卡'。"
}
}
词法定义¶
标识符(Identifier, Ident)¶
使用以下正则描述:
$$ ident::=[A−Za−z][A−Za−z0−9]∗ $$
例如:
greeting,askQuestion,bankName,greetRule等。
赋值与操作符¶
=:用于配置或变量赋值,如case_sensitive = false,VAR bankName = "XX银行"等。{}:用于块结构的开始与结束。关键字:
CONFIG,VAR,STATE,RULE,DEFAULT,MATCH,RESPONSE,GOTO。其他保留字:
true,false(若启用布尔配置)。
字面量(StringLiteral)¶
在 DSL 中,字符串使用英文双引号 " 包裹,内部可包含除 " 之外的任意字符。
注释与空白¶
允许行注释:如
# 这是注释。空白字符(空格、制表符、换行符)一般可在分隔标记的地方任意出现;不影响语义但应被正确忽略或跳过。
语法定义¶
以下使用 EBNF 的语法规则:
使用
[...]表示可选内容(0 或 1 次)。使用
{...}表示可重复 0 至多次。使用
|表示并列可选规则。使用
(...)对表达式进行分组。
脚本整体¶
Script = { ConfigBlock | VarDeclaration | StateBlock }
Script:一个脚本由零个或多个区块组成,每个区块可以是 ConfigBlock、VarDeclaration 或 StateBlock。
配置块(CONFIG)¶
ConfigBlock = "CONFIG" "{" { ConfigLine } "}" ;
ConfigLine = Ident "=" ConfigValue ;
ConfigValue = Ident | BooleanLiteral | StringLiteral ;
BooleanLiteral = "true" | "false" ;
ConfigBlock:以关键字
CONFIG {开始,以}结束,内部由若干行组成(ConfigLine)。ConfigLine:形如
key = value。其中的value可以是标识符、布尔值或字符串字面量等(也可扩展为数字等)。BooleanLiteral:定义了
true或false两种布尔字面量。
示例:
CONFIG {
case_sensitive = false
logLevel = "DEBUG"
}
变量声明(VAR)¶
VarDeclaration = "VAR" Ident "=" StringLiteral ;
VarDeclaration:定义全局可用的变量,例如:
VAR bankName = "XX银行"
状态块(STATE)¶
StateBlock = "STATE" Ident "{" { RuleBlock } [ DefaultBlock ] "}" ;
StateBlock:以
STATE <state_name> { ... }包裹若干规则块和(可选)默认规则块。其中:
Ident为状态名。可以包含 0~N 个
RuleBlock,以及最多 1 个DefaultBlock(DEFAULT {})。
规则块(RULE)¶
RuleBlock = "RULE" Ident "{" RuleContent "}" ;
RuleContent =
"MATCH" StringLiteral
"RESPONSE" StringLiteral
[ "GOTO" Ident ] ;
RuleBlock:以
RULE <rule_name> { ... }开头,内部必须包含:MATCH:用于指定匹配表达式(可为简单字符串或正则字符串)。RESPONSE:匹配成功后的回复文本。可选的
GOTO <state_name>:用于跳转到指定的下一个状态。
示例:
RULE greetRule {
MATCH "你好"
RESPONSE "您好,我是机器人~"
GOTO askQuestion
}
默认规则块(DEFAULT)¶
DefaultBlock = "DEFAULT" "{" DefaultContent "}" ;
DefaultContent =
"RESPONSE" StringLiteral
[ "GOTO" Ident ] ;
DefaultBlock:以
DEFAULT { ... }定义当没有任何RULE命中时的兜底应答。内部包含
RESPONSE字句,且可选GOTO进行跳转。
示例:
DEFAULT {
RESPONSE "抱歉,我没有听清。请再说一次。"
}
综合 EBNF 描述¶
Script = { ( ConfigBlock | VarDeclaration | StateBlock ) } ;
ConfigBlock =
"CONFIG" "{"
{ ConfigLine }
"}" ;
ConfigLine =
Ident "=" ConfigValue ;
ConfigValue =
Ident
| BooleanLiteral
| StringLiteral
| NumberLiteral
BooleanLiteral = "true" | "false" ;
VarDeclaration =
"VAR" Ident "=" StringLiteral ;
StateBlock =
"STATE" Ident "{"
{ RuleBlock }
[ DefaultBlock ]
"}" ;
RuleBlock =
"RULE" Ident "{"
RuleContent
"}" ;
RuleContent =
"MATCH" StringLiteral
"RESPONSE" StringLiteral
[ "GOTO" Ident ] ;
DefaultBlock =
"DEFAULT" "{"
DefaultContent
"}" ;
DefaultContent =
"RESPONSE" StringLiteral
[ "GOTO" Ident ] ;
// --- Lexical tokens ---
Ident = ? [A-Za-z_] [A-Za-z0-9_]* ? ;
StringLiteral = ? '"' ( '\\"' | [^"] )* '"' ? ;
NumberLiteral = ? Digit+ ( '.' Digit+ )? ? ;
Digit = ? [0-9] ? ;