我正在为正式方法和模型中的一个类开发一个项目,我遇到了一些flex / lex的问题。
我们使用flex和C编写一个简单的解析器来检查控制台输入的用户名和密码。我已经得到了各种各样的状态并进行了检查,所以它基本完成了。我只是想让它更好地工作。
我有五种状态:检查用户名的初始状态,并说明检查密码要求(长度,特殊字符,大写字母,数字)。最初,用户输入用户名进行检查。成功时,会要求他们输入密码,并检查上述要求。问题是用户需要在每个州重新键入密码。
我很想知道是否有办法让flex接受适当长度的密码,然后将每个后续状态传递给下一个,这样用户只需输入一次。类似的问题让我this result包括谈论flex的YY_BUFFERS,但是我不确定它是否在类似的方向。
代码如下:
%s PW_START
%s PW_SPECIAL
%s PW_CAPS
%s PW_INT
%s PW_PRINT
%%
<INITIAL>^[a-z]{1}[A-Z]{1}[a-z]{1,6} {
printf("Accepted username: %s\n", yytext);
printf("Namelength: %d\n", yyleng);
printf("Enter a password: ");
BEGIN PW_START;}
<PW_START>^[a-z]{1}([a-zA-Z0-9\[^#@]){5,9} {
printf("Password is proper length: %s\n", yytext);
BEGIN PW_SPECIAL;}
<PW_SPECIAL>^[a-z]{1}[a-zA-Z0-9]{0,8}[\[^#@][a-zA-Z0-9\[^#@]{0,8} {
printf("Password contains >= 1 special character.\n");
printf("Accepted password: %s\n", yytext);
BEGIN PW_CAPS;}
<PW_CAPS>^[a-z]{1}[a-z\[^#@0-9]{0,8}[A-Z][a-zA-Z0-9\[^#@]{0,8} {
printf("Password contains >= 1 capital letter.\n");
BEGIN PW_INT;}
<PW_INT>^[a-z]{1}[a-zA-Z\[^#@]{0,8}[0-9][a-zA-Z0-9\[^#@]{0,8} {
printf("Password contains >= 1 integer.\n");
BEGIN PW_PRINT;}
<PW_PRINT>.* {
printf("Accepted password: %s\n", yytext);}
%%
int main(int argc, char* argv[]){
printf("Enter a username: ");
yylex();
}
答案 0 :(得分:1)
您可以使用yyless(0)
使flex重新扫描令牌。有关详细信息,请参阅Flex manual。
一个例子是
<PW_START>^[a-z]{1}([a-zA-Z0-9\[^#@]){5,9} {
printf("Password is proper length: %s\n", yytext);
BEGIN(PW_SPECIAL);
yyless(0);
}
虽然我认为打印密码真的很粗鲁。如果有人正在看着用户的肩膀怎么办?