我试图创建一个在flex中运行的字符串识别规则,该字符串可以包含转义字符(\ n,\ t,\ r,\,“,'),符号(-,+,*,/, :,_,$,!,#,@,&,〜,^,(,))和a-zA-Z0-9字符,我尝试了以下代码的多种变体,但我不断遇到相同的错误以上。
ESCAPECHAR [\n] | [\t] | [\r] | [\] | ['] | ["]
SYMBOLS [-+*/:_$!#@&~^()]
CHARACTERS [0-9a-zA-Z]
STRING ("({ESCAPECHAR} | {SYMBOLS} | {CHARACTERS})*") | ('({ESCAPECHAR} | {SYMBOLS} | {CHARACTERS})*')
答案 0 :(得分:1)
您最好阅读Flex manual chapter on patterns syntax。它不是很长,并且提供了有关Flex模式语法的完整描述。
以下是您所犯的一些错误:
Flex模式不能包含未加引号的空格(除非您将它们放在带有x
标志的子表达式中)。所以
[\n] | [\t] | [\r] | [\] | ['] | ["]
无效。
此外,\
用于指示:
\n
是换行符),或者[\]
中,\
表示后面的]
应该被视为普通字符,而不是字符类的结尾,这意味着字符类将继续到下一个]
。字符类中的空格字符被认为是带引号的,因此字符类由字符]
,空格,|
,[
和'
组成。 (Flex允许您在字符类中重复字符,因此它不会抱怨存在两个空格字符。)您可能是指[\\]
。无论如何,您应该以与编写其他字符类相同的方式来编写字符类,即在[
和]
中使用一系列字符或转义代码:
[\n\t\r\\ '"]
Flex使您可以通过用引号将字符引起来来对字符进行引号,以便将“({ESCAPECHAR} | {SYMBOLS} | {CHARACTERS})*”视为单个文字字符串,必须在字面上进行匹配在文本中。您可能希望引号是普通字符,因此您应该将引号转义或将其放入单字符字符类:
["]({ESCAPECHAR}|{SYMBOLS}|{CHARACTERS})*["]
同样,有必要从模式中删除空格。
我假设您的意图是仅在实际上将转义时才允许在字符串中出现“转义字符”。您的{ESCAPECHAR}
宏扩展为实际字符的集合,因此它包括换行符,制表符和回车符。它还包括引号和撇号,实际上应该保留它们以终止字符串文字。可能的意思是,如果转义代码前面带有\
(例如C或如上所述的flex本身),则允许它们。在这种情况下,您真正需要写的是
ESCAPECHAR \\[ntr'"]
(即,\\
,其后紧跟字符n
,t
,r
,'
,"
。)尽管如此,这也不是很精确:它不允许使用\\
来表示单个\
,并且迫使用户写"Don\'t just copy code."
和'\"'
,通常都可以在不使用反斜杠转义符的情况下编写两者。