词法分析程序示例"/>
一个简单的 Lex 词法分析程序示例
作为一个学习 Lex 词法分析程序的例子,下面的 lex 程序将会生成一个分析 LaTeX 中命令的词法分析器。下面的程序包含了很多 lex 语言的语法,正则表达式除外。正则表达式的用法网上比较多,这里不再赘述。
/* 第一部分:C++ 开头程序 */
%{
#include <cstdio>
#include <iostream>
#include <vector>
#include <string>
#include <format>enum class token_t : int
{eof = 0,unused,command,
};inline std::string my_command_name;
%}/* 第二部分(零):状态定义 */
%s MAKEATLETTER/* 第二部分(一):正则表达式定义 */
command_no_at [A-Za-z]+
command_with_at [@A-Za-z]+/* 第二部分(二):动作 */
%%
\\makeatletter {BEGIN MAKEATLETTER;my_command_name = yytext;return static_cast<int>(token_t::command);
}
\\makeatother {BEGIN INITIAL;my_command_name = yytext;return static_cast<int>(token_t::command);
}
<INITIAL>\\{command_no_at} |
<MAKEATLETTER>\\{command_with_at} {my_command_name = yytext;return static_cast<int>(token_t::command);
}. { return static_cast<int>(token_t::unused); } /* 抑制输出,注意顺序,必须放在最后 */
%%/* 第三部分:辅助函数 *//* 若 yywrap 返回 0,则继续扫描;返回 1,则词法分析器返回报告文件已结束的 0。*/
int yywrap()
{return 1;
}int main(int argn, char** argv)
{if (argn > 1){if ((yyin = std::fopen(argv[1], "r")) == NULL){std::cout << std::format("Can't open file {0}", argv[1]) << std::endl;return 1;}}elseyyin = stdin;token_t ret;do{ret = static_cast<token_t>(yylex());if (ret > token_t::unused){std::cout << std::endl <<std::format("yylex returns with: {}", static_cast<int>(ret)) << std::endl;std::cout << std::format("yytext is: {}", yytext) << std::endl;switch (ret){case token_t::command:{std::cout << std::format("command name is: {}", my_command_name) << std::endl;break;}default:break;}}} while (ret != token_t::eof);if (yyin)std::fclose(yyin);
}
win_flex --outfile=lex.yy.cpp --noline --wincompat %1
注意,需要使用最新的 MSVC 编译器并打开最新 C++ 标准才能编译。
$$ {\latex}
\@for\relax
\makeatletter
\@for\relax
\makeatother
\@for
$$
yylex returns with: 2
yytext is: \latex
command name is: \latexyylex returns with: 2
yytext is: \relax
command name is: \relaxyylex returns with: 2
yytext is: \makeatletter
command name is: \makeatletteryylex returns with: 2
yytext is: \@for
command name is: \@foryylex returns with: 2
yytext is: \relax
command name is: \relaxyylex returns with: 2
yytext is: \makeatother
command name is: \makeatother
更多推荐
一个简单的 Lex 词法分析程序示例
发布评论