Regex 为什么我的lex文件中的最后一个规则匹配,而我有更好的规则?

Regex 为什么我的lex文件中的最后一个规则匹配,而我有更好的规则?,regex,bison,yacc,lex,bisonc++,Regex,Bison,Yacc,Lex,Bisonc++,我有一个lex文件,其中包含我的规则,例如: PROGRAM return Parser::PROGRAM; PROGRAM_END return Parser::PROGRAM_END; VARIABLES: return Parser::VARIABLES; INSTRUCTIONS: return Parser::INSTRUCTIONS; SKIP return Parser::SKIP; .

我有一个
lex
文件,其中包含我的规则,例如:

PROGRAM           return Parser::PROGRAM;
PROGRAM_END       return Parser::PROGRAM_END;
VARIABLES:        return Parser::VARIABLES;
INSTRUCTIONS:     return Parser::INSTRUCTIONS; 
SKIP              return Parser::SKIP;
.           {
                std::cerr << lineno() << ": ERROR." << std::endl;
                exit(1);
            }
对于这个文件,我只得到:
1:ERROR


这是为什么?我如何解决这一问题?

如注释所示,几乎可以肯定的是,
程序被识别为令牌并传递给解析器。然而,在几乎所有情况下,解析器都会立即请求另一个标记,输入序列中的下一个字符是一个空格,该空格由最后一个规则匹配。该规则打印错误消息并调用
exit()
,从而终止应用程序。(这通常不是一个好主意,但我想这只是一个测试程序。)这就是您将获得的所有输出

如果在调用(f)lex时指定了
-d
命令行参数,则将生成一个调试扫描程序,该程序将报告扫描程序工作时的进度。这是一个非常简单的方法来查看扫描仪中发生了什么。Bison还具有调试模式,如中所述。这些工具非常简单易用,强烈推荐使用

例如,这里是一个快速试验台:

%{
#include <iostream>
#include <cstdlib>
class Parser {
  public:
    enum Token {
      PROGRAM = 257,
      PROGRAM_END, VARIABLES, INSTRUCTIONS, SKIP
    };
};
%}
%option batch noyywrap yylineno c++
%%
PROGRAM           return Parser::PROGRAM;
PROGRAM_END       return Parser::PROGRAM_END;
VARIABLES:        return Parser::VARIABLES;
INSTRUCTIONS:     return Parser::INSTRUCTIONS; 
SKIP              return Parser::SKIP;
.                 {
                    std::cerr << lineno() << ": ERROR." << std::endl;
                    exit(1);
                  }
%%
int main() {
  yyFlexLexer lexer{};
  lexer.set_debug(1);
  while(lexer.yylex() != 0) { }
  return 0;
}
%{
#包括
#包括
类解析器{
公众:
枚举令牌{
程序=257,
程序结束、变量、指令、跳过
};
};
%}
%批量选择包YYLINONO C++
%%
程序返回解析器::程序;
PROGRAM\u END返回解析器::PROGRAM\u END;
变量:返回解析器::变量;
指令:返回解析器::指令;
SKIP返回解析器::SKIP;
.                 {

std::cerr或者您的输入不包含
@sepp2k我用一个示例和此示例的必要规则更新了我的问题。您如何知道
程序
规则没有在该示例中运行?如果您向该规则添加print语句,我肯定您会看到它的输出。无论如何,您可能不应该在u上退出该程序如果您希望它仍然对包含未知字符的输入执行某些操作(而不是带错误消息退出),则不知道字符。我还建议在
-规则中打印有问题的输入。@sepp2k我知道,因为
yacc
文件应该打印捕获的每个规则。如果我使用
YYText()打印
然后什么也没有:
1:错误:
您可能会发现是否在
规则中打印了有问题的字符。我无法告诉您真实代码中缺少哪些规则,因为我没有看到真实代码,但我可以告诉您,在您的示例中,第一个未知字符将是
PRORGAM和
fst
%{
#include <iostream>
#include <cstdlib>
class Parser {
  public:
    enum Token {
      PROGRAM = 257,
      PROGRAM_END, VARIABLES, INSTRUCTIONS, SKIP
    };
};
%}
%option batch noyywrap yylineno c++
%%
PROGRAM           return Parser::PROGRAM;
PROGRAM_END       return Parser::PROGRAM_END;
VARIABLES:        return Parser::VARIABLES;
INSTRUCTIONS:     return Parser::INSTRUCTIONS; 
SKIP              return Parser::SKIP;
.                 {
                    std::cerr << lineno() << ": ERROR." << std::endl;
                    exit(1);
                  }
%%
int main() {
  yyFlexLexer lexer{};
  lexer.set_debug(1);
  while(lexer.yylex() != 0) { }
  return 0;
}
$ g++ lex.yy.cc && ./a.out<<<"PROGRAM fst"
--(end of buffer or a NUL)
--accepting rule at line 14("PROGRAM")
--accepting rule at line 19(" ")
1: ERROR.