一些评论请求(RFC)有以下两条规则:
1. Each comma character must be escaped with a backslash.
2. A backslash that is not being used to escape a comma must be escaped with a backslash.
以下是有效值:
A\,B
A\\\,B
A\\\\\\\,B
以下是无效值:
A\\,B
A,B
A\\\B
我创建了两个Alloy模型。
我的第二个Alloy模型有两个反斜杠签名:
sig Backslash extends Char {}
sig EscapedBackslash extends Char {}
后者当然代表双重反斜杠。前者代表一个反斜杠。
鉴于这两个签名,表达规则非常容易:
Each comma must be preceded by a backslash.
Each backslash must be followed by a comma.
我不需要担心确保某些反斜杠被适当地转义。 EscapedBackslash
签名已经解决了这个问题。
在我的第一个模型中,我只有一个反斜杠的签名:
sig Backslash extends Char {}
实施这两条规则非常困难。事实上,我从未成功实施过这些规则。
正如我之前所说,第二个模型有这个签名:
sig EscapedBackslash extends Char {}
这使我完全避免了检查没有用于转义逗号的每个反斜杠被转义的任务。 这是作弊吗?
这是我的Alloy模型(第二个模型):
one sig Text {
firstChar: Char
}
abstract sig Char {
next: lone Char,
prev: lone Char
}
sig A extends Char {}
sig B extends Char {}
sig C extends Char {}
sig Comma extends Char {}
sig Backslash extends Char {}
sig EscapedBackslash extends Char {}
fact Text_Structure {
// If the i'th character is c and c.next is c', then c'.prev equals c
all c: Char | some c.next => c.next.prev = c
// The first character has no previous character
no Text.firstChar.prev
// No cycles in the forward direction, i.e., if the i'th character is c, then the
// i'th + n character cannot be c
no c: Char | c in c.^next
// No cycles in the backward direction, i.e., if the i'th character is c, then the
// i'th - n character cannot be c
no c: Char | c in c.^prev
// This is not necesssary. I just don't like to see miscellaneous relations.
// This says that if a character is not in the string, then it has no next or previous character.
all c: Char | c not in Text.firstChar.*next => no c.next and no c.prev
}
// Rule: Every comma MUST be escaped.
fact Every_Comma_Escaped {
// The firstChar cannot be a comma
Text.firstChar not in Comma
all c: Text.firstChar.*next | c in Comma => c.prev in Backslash
}
// Rule: If a backslash is not being used to escape a character,
// then the backslash MUST be escaped, i.e., the single backslash
// must occur only when preceding a comma.
fact Every_Literal_Backslash_Escaped {
all c: Text.firstChar.*next | (c in Backslash) => (some c.next) and (c.next in Text.firstChar.*next) and (c.next in Comma)
}