4

假设我有以下 EBNF:

ProductNo   ::= Digitgroup "-" Lettergroup;
Digitgroup  ::= Digit Digit? Digit? Digit?;
Digit       ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9";
Lettergroup ::= Letter Letter? Letter? Letter? Letter?;
Letter      ::= "A" | "B" | "C" | "D" | "E" | "F" | "G"
            | "H" | "I" | "J" | "K" | "L" | "M" | "N"
            | "O" | "P" | "Q" | "R" | "S" | "T" | "U"
            | "V" | "W" | "X" | "Y" | "Z";

现在我想为 ProductNo = 5 设置最大令牌

例子:

Input : 1-A      (EBNF valid and Token < 5)
Input : 023-A    (EBNF valid and Token < 5)
Input : 0231-ABI (currently EBNF valid but Token = 8 > 5 so this should not be valid)
Input : 022-ABCDE(currently EBNF valid but Token = 9 > 5 so this should not be valid)

正如您在此示例输入中看到的那样,数字和字母的组合可以变化,只要其 EBNF 符合 (min 1 Digit max 4 Digit), (min 1 Letter max 5 Letter) 但令牌的总和必须是 < = 5,包括“-”。

问题:除了写下每个有效的字母和数字组合之外,还有其他方法吗?

我目前的解决方案:

ProductNo   ::= Token Token Token Token? Token?;
Token       ::= Digit | Letter | "-";
Digit       ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9";
Letter      ::= "A" | "B" | "C" | "D" | "E" | "F" | "G"
            | "H" | "I" | "J" | "K" | "L" | "M" | "N"
            | "O" | "P" | "Q" | "R" | "S" | "T" | "U"
            | "V" | "W" | "X" | "Y" | "Z";

问题:ProductNo (Digitgroup, "-", Lettergroup) 的组成没有被复制。所以我需要将两个 EBNF 合二为一,但我真的不知道如何做到这一点。

4

2 回答 2

3

我假设您使用的是 W3C 表示法:http ://www.w3.org/TR/REC-xml/#sec-notation ,而不是标准 ISO 表示法:http ://en.wikipedia.org/wiki/ Extended_Backus%E2%80%93Naur_Form

如果我错了,请说明您使用的是哪个 EBNF!

在 W3C 表示法中,您可以使用:

Digit       ::= [0-9]
Letter      ::= [A-Z]
GoodFormat  ::= Digit+ "-" Letter+
Token       ::= Digit | Letter | "-"
TooLong     ::= Token Token Token Token Token Token+
ProductNo   ::= GoodFormat - TooLong
于 2013-11-08T16:35:00.947 回答
0

我认为有一个比写下每个有效组合更聪明的解决方案:

ProductNo   ::= Case1 | Case2 | Case3
Case1       ::= Digit Digit? Digit? "-" Letter;
Case2       ::= Digit "-" Letter Letter? Letter?;
Case3       ::= Digit Digit? "-" Letter Letter?;
Digit       ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9";
Letter      ::= "A" | "B" | "C" | "D" | "E" | "F" | "G"
            | "H" | "I" | "J" | "K" | "L" | "M" | "N"
            | "O" | "P" | "Q" | "R" | "S" | "T" | "U"
            | "V" | "W" | "X" | "Y" | "Z";

但我不知道是否有更聪明的理由这样做。我希望这个解决方案有点帮助。

于 2013-11-03T15:05:46.470 回答