Lex,一个Unix词法分析器工具,允许您按如下方式定义此模式:[^\a]
在此示例中,它指定除字符a
之外的任何内容。我们试图在流氓中做同样的事情,但无法弄清楚如何在我们的迷你解析器中指定它。
import String;
import util::FileSystem;
lexical CommentStart = ^"/*";
lexical CommentEnd = "*/";
lexical LineComment = ^"//";
lexical Any = ????;
syntax Badies = CommentStart | CommentEnd | LineComment | Any;
/* Parses a single string */
int parseLine (str line) {
pt = parse(#Badies, line);
visit (pt) {
case CommentStart:
return 1;
case CommentEnd:
return 2;
case LineComment:
return 3;
}
return 4;
}
也许我们的问题是错误的,但如果有人能帮助定义我们的“除了”正则表达式以外的任何东西,我们将不胜感激。
在某些情况下可能适合的另一种可能性是使用字符范围然后减去不需要的字符。例如,JSON字符串中的合法字符是除ASCII控制字符,双引号和反斜杠或转义字符序列之外的任何Unicode字符。你可以表达为:
lexical JsonChar
= [\u0020-\U10FFFF] - [\"\\]
| [\\] [\" \\ / b f n r t]
| [\\] [u] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F]
;
(注意6位Unicode转义的大写字母U。)
或者,等同于(我希望)与![\a00-\a19 \" \\] | ...
。甚至![] - [\a00-\a19 \" \\] | ...
。
例如:
rascal>parse(#JsonChar, "\U01f41d")
JsonChar: (JsonChar) `🐝`
(是的,Unicode现在几乎附带一个Rascal徽标表情符号!)
如果合法的Unicode字符的范围是每一个扩展的(或者如果Rascal使它自己的扩展),可能会有区别,但它可能主要取决于你的大脑是什么。 (JSON标准将其写为“%x20-21 / %x23-5B / %x5D-10FFFF
”,采用RFC ABNF表示法。)
lexical Any = ![]
的!运算符否定了字符类。请注意,出于实际目的,0 EOF字符不包含在否定中。