re2cの始めかた
re2cを始めるには、小さいプログラムだと理解が早いと思います。
ここでは、"Hello,World"を字句解析するプログラムを用意しました。
ここでは、"Hello,World"を字句解析するプログラムを用意しました。
文字もしくは文字列パタンに1対1で対応した番号を返す処理を行います。
サンプルコード"Hello World"
- hello.re
#include <stdio.h>
#include <stdlib.h>
enum {
TOKEN_HELLO = 1,
TOKEN_WORLD = 2,
TOKEN_COMMA = 3,
TOKEN_ERR = -1
};
char* yyin;
char* yymarker;
int yylex()
{
/*!re2c
re2c:define:YYCTYPE = "char";
re2c:define:YYCURSOR = yyin;
re2c:define:YYMARKER = yymarker;
re2c:yyfill:enable = 0;
re2c:indent:top = 1;
"Hello" { return TOKEN_HELLO; }
"World" { return TOKEN_WORLD; }
"," { return TOKEN_COMMA; }
[^] { return TOKEN_ERR; }
*/
}
int main( int argc, char* argv[] )
{
char* pBuf = "Hello,World";
yyin = pBuf;
printf( "str = %s\n", pBuf );
printf( "yylex = %d\n", yylex() );
printf( "yylex = %d\n", yylex() );
printf( "yylex = %d\n", yylex() );
printf( "yylex = %d\n", yylex() );
printf( "yylex = %d\n", yylex() );
return 0;
}
コンパイル
re2c -o hello.cpp hello.re g++ -o run.x hello.cpp
- 最適化
re2c -is -o hello.cpp hello.re
-i #lineを表示しません。
-s switch文の代わりにをネストしたif文を吐き出します。
コードは最適化されます。(人には読みづらくなります)
-s switch文の代わりにをネストしたif文を吐き出します。
コードは最適化されます。(人には読みづらくなります)
結果
- 実行
./run.x
str = Hello,World yylex = 1 yylex = 3 yylex = 2 yylex = -1 yylex = -1
説明
re2cの変換は、/*!re2cから*/で囲まれた部分が対象となります。
/*!re2c この部分が変換対象 */
最低限、次が必要です。
re2c:define:YYCTYPE = "char"; re2c:define:YYCURSOR = yyin; re2c:define:YYMARKER = yymarker; re2c:yyfill:enable = 0;
YYCTYPEには、文字型を指定します。普通は"char"もしくは"unsigned char"になります。
YYCURSORには、解析する文字列の先頭ポインタを示す変数名を指定します。
YYMARKERには、解析中に現在の位置を示すポインタ変数を指定します。
yyfill:enable=0とすることで、バッファに充填する関数を必要としなくなります。大きなソースコードの場合は、これを有効(1)にし、fill関数を用意することになります。
YYCURSORには、解析する文字列の先頭ポインタを示す変数名を指定します。
YYMARKERには、解析中に現在の位置を示すポインタ変数を指定します。
yyfill:enable=0とすることで、バッファに充填する関数を必要としなくなります。大きなソースコードの場合は、これを有効(1)にし、fill関数を用意することになります。