Posted on 2014-04-10 09:43
S.l.e!ep.¢% 閱讀(1935)
評論(0) 編輯 收藏 引用 所屬分類:
yacc
實現解析c++ #include 頭文件的語法, 暫時沒有實現 嵌套解析 #include
codegen.l
%option?noyywrap
%option?yylineno
%{
#include?<stdio.h>
#include?<stdlib.h>
#include?"codegen.tab.h"
#define?YYDEBUG?0?//?將這個變量設置為1則表示啟動Yacc的調試功能
#define?YYERROR_VERBOSE
extern?int?yylex();
extern?void?yyerror(char*?s);
%}
%x?_STATE_INCLUDE_
%x?_STATE_INCLUDE_FILE_
%%
"#"[?\t]*"include"?{?
????????BEGIN?_STATE_INCLUDE_;??//?進入?_STATE_INCLUDE_?狀態
????????return?TOKEN_INCLUDE;
????}
<_STATE_INCLUDE_>[/"|<]*?{
????????BEGIN?_STATE_INCLUDE_FILE_;?//?進入?_STATE_INCLUDE_FILE_?狀態
????????return?*yytext;?//?返回引號或尖括號
????}
????
<_STATE_INCLUDE_FILE_>[/"|>]?{
????????return?TOKEN_INCLUDE_FILE;?//?返回頭文件標記
????};
????
[?/t/n]?;?//?對于額外的空白不處理
%%
int?main(?int?argc,?char?**argv?)
{
????yyparse();
}
void?yyerror(char?*s)
{
????fprintf(stderr,?"error:?%s\n",?s);
}
codegen.y
%{
#include?<stdio.h>
#include?<stdlib.h>
%}
%token?TOKEN_INCLUDE?
%token?TOKEN_INCLUDE_FILE
%%
program:
????|?program?include_process
????;
include_process:
????TOKEN_INCLUDE?'<'?TOKEN_INCLUDE_FILE?'>'?
????{
????????printf("include?=?[%s]?\n",?$3?);
????}
????|?TOKEN_INCLUDE?'/"'?TOKEN_INCLUDE_FILE?'/"'
????{
????????printf("include?=?[%s]?\n",?$3?);????????
????}
????
%%
---------------------------------------------------
2014.04.11
上面的解析是有問題的, 當輸入 #include <abc> 時,解析結果為空, 看了下書, 原因是在 返回 TOKEN_INCLUDE_FILE 標記時, 沒有對 全局變量
yylval 進行賦值
yylval 是一個int 的類型, 在bison生成的代碼, yylval是用 YYSTYPE 定義的,可以通過 %union 修改 YYSTYPE 的定義
修改后的代碼如下:
codegen.l
%option?noyywrap
%option?yylineno
%{
#include?<stdio.h>
#include?<stdlib.h>
#include?"codegen.tab.h"
#define?YYDEBUG?1?//?將這個變量設置為1則表示啟動Yacc的調試功能
#define?YYERROR_VERBOSE
extern?int?yylex();
extern?void?yyerror(char*?s);
%}
%x?_STATE_INCLUDE_BEGIN_
%x?_STATE_INCLUDE_FILE_
%x?_STATE_INCLUDE_END_
%%
^"#include"?{?
????????BEGIN?_STATE_INCLUDE_BEGIN_;
????????return?TOKEN_INCLUDE;
????}
<_STATE_INCLUDE_BEGIN_>"<"?{
????????BEGIN?_STATE_INCLUDE_FILE_;
????????return?'<';
????}
????
<_STATE_INCLUDE_FILE_>[^\">]+?{
????????BEGIN?_STATE_INCLUDE_END_;
????????yylval.m_lpStr?=?strdup(yytext);
????????return?TOKEN_INCLUDE_FILE;
????}
????
<_STATE_INCLUDE_END_>">"?{
????????return?'>';
????}
[?/t/n]?;?//?對于額外的空白不處理
.?{?printf("other");?}
%%
int?main(?int?argc,?char?**argv?)
{
????yyparse();
}
void?yyerror(char?*s)
{
????fprintf(stderr,?"error:?%s\n",?s);
}
codegen.y
%{
#include?<stdio.h>
#include?<stdlib.h>
%}
%union
{
?????char*?m_lpStr;
}
%token?TOKEN_INCLUDE
%token?TOKEN_INCLUDE_FILE
%%
program:
????|?program?include_process
????;
include_process:
????TOKEN_INCLUDE?'<'?TOKEN_INCLUDE_FILE?'>'
????{
????????printf("include?=?[%s]?\n",?yylval.m_lpStr?);
????????free(?yylval.m_lpStr?);
????}
????
%%
修改后的問題
1. 輸出時多了一個空格 和 換行
2. 實現一個 include 解析, 需要這么多的獨占狀態么?