C:\home\SVGCats_src\src\blex3.c
1|/************************************************************************** 2|* 1. <<< 基本字句解析 ver.3 (BLex3) >>> 3|***************************************************************************/ 4| 5|#include "mixer_precomp.h" 6|// #pragma hdrstop ("mixer_precomp") 7| 8|#ifdef USES_MXP_AUTOINC 9|#include <BLex3.ah> /* Auto include header, Look at mixer-... folder */ 10|#endif 11| 12| 13| 14| 15|/*---------------------------------------------------------------------*/ 16|/* 2. <<<◆(BLex3) 基本字句解析 ver.3 >>> */ 17|/*---------------------------------------------------------------------*/ 18| 19| 20|/************************************************************************** 21|* 3. <<< [BLex3_init] 初期化する >>> 22|*【引数】 23|* ・BLex3* m; 基本字句解析 ver.3 24|*【補足】 25|*・ 26|***************************************************************************/ 27|#ifdef USES_OTHER 28|void BLex3_init( BLex3* m ) 29|{ 30| int a; 31| 32| ERRORS_INITCHK( m, 0 ); 33| ASSERT( a >= 0 ); 34| 35| m->a = a; 36| 37| ERRORS_FINISHCHK_FOR_INIT( BLex3_finish ); 38|} 39|#endif 40| 41| 42| 43|/************************************************************************** 44|* 4. <<< [BLex3_finish] 後始末する >>> 45|***************************************************************************/ 46|#ifdef USES_OTHER 47|void BLex3_finish( BLex3* m ) 48|{ 49| ERRORS_INITCHK( m, 1 ); 50| ERRORS_FINISHCHK_FOR_FINISH( BLex3_finish ); 51| 52| Other_finish( &m->a ); 53|} 54|#endif 55| 56| 57| 58|/************************************************************************** 59|* 5. <<< [BLex3_assemble] 1つのファイルを字句解析をする >>> 60|*【引数】 61|* ・BLex3* m; 基本字句解析 ver.3 62|*【補足】 63|*・ 64|***************************************************************************/ 65|BLex3_BackMsg BLex3_assemble( BLex3* m, const char* in_path, const char* out_path ) 66|{ 67|#if 0 68| BLex3_BackMsg msg; 69| 70| BLex3_openFile( &lex, in_path, out_path ); 71| c_try { 72| for (;;) { 73| for ( BLex3_forEachParser( &lex, &par, BLex3_Parser ) ) { 74| BLex3_Parser_parse( *par, &lex ); 75| } 76| do { 77| for ( BLex3_forEachActor( &lex, &act, BLex3_Actor ) ) { 78| msg = BLex3_Actor_act( *act, &lex ); 79| if ( msg & BLex3_BreakActLoop ) break; 80| } 81| } while ( msg & BLex3_ReActor ); 82| if ( msg & BLex3_BreakTokenLoop ) break; 83| } 84| } 85| c_finally { 86| BLex3_closeFile( &lex ); 87| } c_finally; 88| 89| return msg; 90|#endif 91|return BLex3_NextActor; 92|} 93| 94|/************************************************************************** 95|* 6. <<< [BLex3_next] ファイルポインタを進める >>> 96|*【引数】 97|* ・BLex3* m; 基本字句解析 ver.3 98|*【補足】 99|*・ 100|***************************************************************************/ 101|void BLex3_next( BLex3* m, int n ) 102|{ 103|#if 0 104| for ( BLex3_forEachCounter( &lex, &cnt, BLex3_Counter ) ) { 105| BLex3_Counter_count( *cnt, &lex, n ); 106| } 107|#endif 108|} 109| 110|/************************************************************************** 111|* 7. <<< [BLex3_printLastMsg] 字句解析の最終結果を表示する >>> 112|*【引数】 113|* ・BLex3* m; 基本字句解析 ver.3 114|*【補足】 115|*・たとえば、エラーの数や、行数などを表示します。 116|***************************************************************************/ 117|void BLex3_printLastMsg( BLex3* m ) 118|{ 119|#if 0 120| for ( BLex3_forEachParser( m, &par, BLex3_Parser ) ) { 121| BLex3_Parser_printLastMsg( *par, &lex ); 122| } 123| for ( BLex3_forEachActor( m, &act, BLex3_Actor ) ) { 124| BLex3_Actor_printLastMsg( *act, &lex ); 125| } 126| for ( BLex3_forEachCounter( m, &cnt, BLex3_Counter ) ) { 127| BLex3_Counter_printLastMsg( *cnt, &lex, n ); 128| } 129|#endif 130|} 131| 132|/*---------------------------------------------------------------------*/ 133|/* 8. <<<◆(BLex3_Pos) ファイル・アドレス >>> */ 134|/*---------------------------------------------------------------------*/ 135| 136|BLex3_Pos BLex3_nullPos = { -1L, BLex3_SJisUnknown }; 137| 138|/************************************************************************** 139|* 9. <<< [BLex3_Pos_print] デバッグ表示する >>> 140|*************************************************************************/ 141|#ifndef ERRORS_CUT_DEBUG_TOOL 142|void BLex3_Pos_print( BLex3_Pos* m, const char* title ) 143|{ 144| Errors_printf( "%sBLex3_Pos[%p] pos=0x%lX, sjis_type=%d", 145| title, m, m->pos, m->sjis_type ); 146|} 147|#endif 148| 149|/*---------------------------------------------------------------------*/ 150|/* 10. <<<◆(BLex3_Engine) 字句解析エンジン >>> */ 151|/*---------------------------------------------------------------------*/ 152| 153|void BLex3_Engine_fillSJisBuf( BLex3_Engine*, char* buf_first, 154| char* buf_over, int firstType ); 155| 156|/************************************************************************** 157|* 11. <<< [BLex3_Engine_init] 初期化する >>> 158|*【引数】 159|* ・BLex3_Engine* m; 字句解析エンジン 160|* ・char* path; 入力ファイルパス 161|* ・void* buf; 内部バッファ領域として使う領域の先頭アドレス 162|* ・int buf_size; buf のメモリサイズ(バイト) 163|* ・int sec_size; ディスクのセクタサイズ 164|*【補足】 165|*・セクタサイズは、API の GetDiskFreeSpace から取得できます。 166|*・buf_size のうち、実際に使用されるサイズは buf_size - 1 以下で最も大きい 167|* sec_size の倍数です。これは、sec_size の倍数の余る分が '\0' で 168|* 埋められ、これを文字列の末尾文字 '\0' として使用しているためです。 169|***************************************************************************/ 170|void BLex3_Engine_init( BLex3_Engine* m, const char* path, 171| void* buf, int buf_size, int sec_size ) 172|{ 173| int s = sec_size; 174| int sft = 0; 175| 176| /* セクタサイズは 2 の n 乗であること */ 177| ASSERT( s != 0 ); 178| while ( ( s & 1 ) == 0 ) { s >>= 1; sft++; } 179| ASSERT( s == 1 ); 180| 181| /* ファイルオープン */ 182| m->f = FileX_open( path, "rb" ); 183| 184| /* メンバ変数を初期化する */ 185| m->buf = buf; 186| m->buf_over = (char*)buf + ( ((buf_size - 1) >> sft) << sft ); 187| m->sec_size = sec_size; 188| m->sec_sft = sft; 189| 190| m->sjis_buf = NULL; 191| 192| m->pos.pos = 0L; 193| m->fp = buf; 194| 195| /* 内部バッファの最後の使わない部分は '\0' で埋める */ 196| memset( m->buf_over, 0, (char*)buf + buf_size - m->buf_over ); 197| 198| /* ファイルの内容を buf に読み込む */ 199| { 200| int count, result; 201| 202| count = (buf_size - 1) >> sft; 203| result = fread( buf, sec_size, count, m->f ); 204| if ( result < count ) { 205| fseek( m->f, 0, SEEK_END ); 206| m->eof_first = (char*)buf + ftell( m->f ); 207| memset( m->eof_first, 0, m->buf_over - m->eof_first ); 208| } 209| else { 210| m->eof_first = (char*)buf + buf_size; 211| } 212| } 213| 214| ERRORS_FINISHCHK_FOR_INIT( BLex3_Engine_finish ); 215|} 216| 217|/************************************************************************** 218|* 12. <<< [BLex3_Engine_finish] 後始末する >>> 219|***************************************************************************/ 220|void BLex3_Engine_finish( BLex3_Engine* m ) 221|{ 222| ERRORS_FINISHCHK_FOR_FINISH( BLex3_Engine_finish ); 223| 224| fclose( m->f ); 225|} 226| 227| 228| 229|/************************************************************************** 230|* 13. <<< [BLex3_Engine_print] デバッグ表示する >>> 231|***************************************************************************/ 232|#ifndef ERRORS_CUT_DEBUG_TOOL 233|void BLex3_Engine_print( BLex3_Engine* m, const char* title ) 234|{ 235| int n; 236| 237| Errors_printf( "%sbuf = %p, buf_over = %p, eof_first = %p, offset_over = %p", 238| title, m->buf, m->buf_over, m->eof_first, m->offset_over ); 239| Errors_printf( "%ssec_size = %d, sec_sft = %d", 240| title, m->sec_size, m->sec_sft ); 241| Errors_printf( "%spos(buf_first) = 0x%lX, pos(fp) = 0x%lX, fp = %p", 242| title, m->pos.pos, m->pos.pos + (m->fp - m->buf), m->fp ); 243| 244| n = m->buf_over - m->buf; 245| WX( m->buf, n ); 246| n = m->buf_over - m->fp; 247| WX( m->fp, n ); 248| if ( m->sjis_buf == NULL ) 249| Errors_printf( "%ssjis_buf = NULL", title ); 250| else { 251| n = m->buf_over - m->buf; 252| WX( m->sjis_buf, n ); 253| n = m->buf_over - m->fp; 254| WX( m->sjis_buf + (m->fp - m->buf), n ); 255| } 256|} 257|#endif 258| 259|/************************************************************************** 260|* 14. <<< [BLex3_Engine_setSJisBuf] Shift Jis 判定用バッファを使用する >>> 261|*【引数】 262|* ・void* buf; Shift Jis 判定用バッファに使う領域の先頭アドレス 263|* ・int buf_size; buf のサイズ(バイト)内部バッファと同じであること 264|***************************************************************************/ 265|void BLex3_Engine_setSJisBuf( BLex3_Engine* m, void* buf, 266| int buf_size ) 267|{ 268| ASSERT( m->pos.pos == 0 ); 269| ASSERT( m->buf_over - m->buf <= buf_size ); 270| 271| m->sjis_buf = buf; 272| 273| BLex3_Engine_fillSJisBuf( m, m->buf, m->buf_over, 274| _ismbblead( *m->buf ) ? BLex3_SJisFirst : BLex3_Ascii ); 275|} 276| 277| 278| 279|/************************************************************************** 280|* 15. <<< [BLex3_Engine_fillSJisBuf] Shift Jis 判定用バッファに情報を格納する >>> 281|*【引数】 282|* ・char* buf_first; 判定を開始する内部バッファのアドレス 283|* ・char* buf_over; 最後に判定する次の内部バッファのアドレス 284|* ・int firstType; buf_first の位置のバイト文字のタイプ(BLex3_Ascii など) 285|*【補足】 286|*・内部用です。 287|***************************************************************************/ 288|void BLex3_Engine_fillSJisBuf( BLex3_Engine* m, char* buf_first, 289| char* buf_over, int firstType ) 290|{ 291| char* p; /* 内部バッファのポインタ */ 292| char* p2; /* Shift Jis 判定バッファのポインタ */ 293| 294| if ( buf_first == buf_over ) return; 295| 296| /* 最初のバイト文字の情報を格納する */ 297| p2 = m->sjis_buf + (buf_first - m->buf); 298| *p2 = firstType; 299| if ( firstType == BLex3_SJisUnknown ) { 300| memset( p2, BLex3_SJisUnknown, buf_over - buf_first ); 301| ERRORS_WARNING_0( "filled SJisUnknown" ); 302| return; 303| } 304| else if ( firstType == BLex3_SJisFirst ) { 305| *(p2 + 1) = BLex3_SJisSecond; 306| p = buf_first + 2; 307| p2 += 2; 308| } 309| else { 310| p = buf_first + 1; 311| p2 ++; 312| } 313| 314| /* 途中のバイト文字の情報を格納する */ 315| while ( p < buf_over - 1 ) { 316| if ( _ismbblead( *p ) ) { 317| p += 2; 318| *p2 = BLex3_SJisFirst; 319| *(p2 + 1) = BLex3_SJisSecond; 320| p2 += 2; 321| } 322| else { 323| p ++; 324| *p2 = BLex3_Ascii; 325| p2 ++; 326| } 327| } 328| 329| /* 最後のバイト文字の情報を格納する */ 330| if ( p < buf_over ) { /* except 2byte ch */ 331| if ( _ismbblead( *p ) ) 332| *p2 = BLex3_SJisFirst; 333| else 334| *p2 = BLex3_Ascii; 335| } 336|} 337| 338| 339|/************************************************************************** 340|* 16. <<< [BLex3_Engine_getFilePtr] アクセス用ファイルポインタを取得する >>> 341|*【引数】 342|* ・BLex3_Engine* m; 字句解析エンジン 343|* ・int offsetOver; ファイルポインタからアクセスできる最大のオフセット+1 344|* ・char* 返り値; ファイルポインタ、ファイルの末尾より後=NULL 345|*【補足】 346|*・BLex3_Engine_next 関数などを呼び出したら、前に本関数から取得したファイル 347|* ポインタは使えなくなります。 348|*・返り値のファイルポインタ fp は、指定した最大のオフセット(fp + offsetOver) 349|* までアクセスできます。指定した offsetOver を超えて、内部バッファの最後まで 350|* アクセスすることもできます。 351|*・offsetOver に 0 を指定したときは、 352|* 内部バッファの最後(BLex3_Engine_getOverPtr() - 1)までアクセスできます。 353|* そのとき、少なくとも1バイトはアクセスできます。 354|*・n 文字のキーワードと一致するかどうか判定するときは、offsetOver に n を 355|* 指定します。ただし、in と inter のように、そのキーワードから始まる 356|* 別のキーワードである可能性があることに注意してください。 357|*・ファイルの末尾より後に相当する内部バッファには、'\0' が入ります。 358|*・本関数は、内部バッファにファイルデータを読み込むときと読みこまないときが 359|* あります。 360|***************************************************************************/ 361|char* BLex3_Engine_getFilePtr( BLex3_Engine* m, int offsetOver ) 362|{ 363| int offset = ( (m->fp - m->buf) & (m->sec_size - 1) ); 364| int count, result; 365| char* readAdr; 366| 367| ASSERT( offsetOver >= 0 ); 368| ASSERT( m->buf + m->sec_size + offsetOver <= m->buf_over ); 369| /* offsetOver が大きすぎます */ 370| 371| /* 内部バッファの内容をファイルポインタのある前方の位置のデータに戻す */ 372| if ( m->fp < m->buf ) { 373| char* fp0 = m->fp - offset; 374| 375| m->pos.pos += (m->fp - offset) - m->buf; 376| ASSERT( m->pos.pos >= 0 ); 377| fseek( m->f, m->pos.pos, SEEK_SET ); 378| 379| readAdr = m->buf; 380| count = (m->buf_over - m->buf) >> m->sec_sft; 381| result = fread( readAdr, m->sec_size, count, m->f ); 382| if ( result == 0 ) { 383| fseek( m->f, m->pos.pos + offset, SEEK_SET ); /* for next feof */ 384| fgetc( m->f ); /* for next feof */ 385| } 386| if ( result == 0 && feof( m->f ) ) { 387| m->fp = m->buf + offset; 388| m->eof_first = m->buf + offset; 389| return NULL; 390| } 391| else if ( result < count ) { 392| fseek( m->f, 0, SEEK_END ); 393| m->eof_first = m->buf + ( ftell( m->f ) - m->pos.pos ); 394| if ( m->sjis_buf != NULL ) { 395| BLex3_Engine_fillSJisBuf( m, readAdr, m->eof_first, 396| m->pos.sjis_type ); 397| } 398| } 399| else { 400| m->eof_first = m->buf_over; 401| if ( m->sjis_buf != NULL /*&& result > 0*/ ) { /* BLEX3_USES_OLD_010831 */ 402| BLex3_Engine_fillSJisBuf( m, readAdr, 403| readAdr + (result << m->sec_sft), m->pos.sjis_type ); 404| } 405| } 406| m->fp = m->buf + offset; 407| ASSERT( m->fp + offsetOver <= m->buf_over ); 408| 409| if ( offsetOver == 0 ) m->offset_over = m->buf_over; 410| else m->offset_over = m->fp + offsetOver; 411| return m->fp; 412| } 413| 414| /* offsetOver までアクセスできないときは、内部バッファをスクロールする */ 415| if ( m->fp + offsetOver > m->buf_over || m->fp >= m->buf_over ) { 416| char* fp0 = m->fp - offset; 417| int sjis_type = BLex3_Ascii; 418| int seekPos; 419| 420| /* 内部バッファの外を読みこむとき */ 421| if ( fp0 >= m->buf_over ) { 422| seekPos = (fp0 - m->buf) + m->pos.pos; 423| fseek( m->f, seekPos, SEEK_SET ); 424| if ( fp0 >= m->buf_over + m->sec_size ) { 425| sjis_type = m->pos.sjis_type; 426| } 427| else { 428| if ( m->sjis_buf != NULL ) 429| sjis_type = *( m->sjis_buf + (m->buf_over - m->buf) - 1 ); 430| } 431| readAdr = m->buf; 432| count = (m->buf_over - m->buf) >> m->sec_sft; 433| } 434| /* 内部バッファの一部をスクロールするとき */ 435| else { 436| memmove( m->buf, fp0, m->buf_over - fp0 ); 437| memmove( m->sjis_buf, m->sjis_buf + (fp0 - m->buf), m->buf_over - fp0 ); 438| seekPos = m->pos.pos + (m->buf_over - m->buf); 439| fseek( m->f, seekPos, SEEK_SET ); 440| readAdr = m->buf + (m->buf_over - fp0); 441| count = (fp0 - m->buf) >> m->sec_sft; 442| if ( m->sjis_buf != NULL ) 443| sjis_type = *( m->sjis_buf + (fp0 - m->buf) - 1 ); 444| } 445| 446| /* 読みこむ */ 447| result = fread( readAdr, m->sec_size, count, m->f ); 448| if ( result == 0 ) { 449| fseek( m->f, seekPos, SEEK_SET ); fgetc( m->f ); /* for next feof */ 450| } 451| if ( m->sjis_buf != NULL && ! feof(m->f) ) { 452| if ( sjis_type != BLex3_SJisUnknown ) { 453| if ( sjis_type == BLex3_SJisFirst ) 454| sjis_type = BLex3_SJisSecond; 455| else 456| sjis_type = _ismbblead( *readAdr ) ? BLex3_SJisFirst : BLex3_Ascii; 457| } 458| BLex3_Engine_fillSJisBuf( m, readAdr, 459| readAdr + (result << m->sec_sft), sjis_type ); 460| } 461| m->pos.pos += fp0 - m->buf; 462| 463| /* EOF より後は、'\0' を埋め、m->eof_first を設定する */ 464| if ( result < count ) { 465| int fSizeOfs; 466| 467| if ( m->eof_first < m->buf_over ) { 468| m->eof_first -= m->fp - offset - m->buf; 469| memset( readAdr, 0, m->buf_over - readAdr ); 470| } 471| else { 472| fseek( m->f, 0, SEEK_END ); 473| fSizeOfs = ftell( m->f ) % m->sec_size; 474| m->eof_first = readAdr + (result << m->sec_sft) + fSizeOfs; 475| BLex3_Engine_fillSJisBuf( m, readAdr, m->eof_first, sjis_type ); 476| memset( m->eof_first, 0, m->sec_size - fSizeOfs ); 477| } 478| } 479| else 480| m->eof_first = m->buf_over; 481| 482| m->fp = m->buf + offset; 483| if ( offsetOver == 0 ) m->offset_over = m->buf_over; 484| else m->offset_over = m->fp + offsetOver; 485| return ( m->fp >= m->eof_first ) ? NULL : m->fp; 486| } 487| 488| /* 読みこむ必要が無いとき */ 489| else { 490| if ( offsetOver == 0 ) m->offset_over = m->buf_over; 491| else m->offset_over = m->fp + offsetOver; 492| return ( m->fp >= m->eof_first ) ? NULL : m->fp; 493| } 494|} 495| 496| 497|/************************************************************************** 498|* 17. <<< [BLex3_Engine_getFilePtrByPos] アクセス用ファイルポインタを取得する >>> 499|*【引数】 500|* ・BLex3_Engine* m; 字句解析エンジン 501|* ・long pos; ファイル・アドレス 502|* ・char* 返り値; ファイルポインタ 503|*【補足】 504|*・pos に内部バッファの外(末尾の次を除く)に相当するアドレスは指定できません。 505|***************************************************************************/ 506|char* BLex3_Engine_getFilePtrByPos( BLex3_Engine* m, long pos ) 507|{ 508| char* fp = m->buf + ( pos - m->pos.pos ); 509| 510| ASSERT( fp >= m->buf && fp <= m->buf_over ); 511| 512| return fp; 513|} 514| 515|/************************************************************************** 516|* 18. <<< [BLex3_Engine_getFilePtrByPos2] アクセス用ファイルポインタを取得する >>> 517|*【補足】 518|*・pos に内部バッファの外が指定できる BLex3_Engine_getFilePtrByPos 関数です。 519|* ただし、ASSERT に引っかからないだけで、内部バッファの外の場合、 520|* 返り値のファイルポインタを使って、ファイルの内容にアクセスできません。 521|* ファイルポインタの位置の比較のために使います。 522|***************************************************************************/ 523|char* BLex3_Engine_getFilePtrByPos2( BLex3_Engine* m, long pos ) 524|{ 525| return m->buf + ( pos - m->pos.pos ); 526|} 527| 528|/************************************************************************** 529|* 19. <<< [BLex3_Engine_getOverPtr] 内部バッファに入っている最後のデータの次のアドレスを返す >>> 530|*【引数】 531|* ・BLex3_Engine* m; 字句解析エンジン 532|* ・char* 返り値; アクセスできる領域の次のアドレス 533|*【補足】 534|*・返り値は、内部バッファのサイズや、ファイルの末尾を考慮しています。 535|*・EOF(EndOfFile)かどうかは、BLex3_Engine_getFilePtr 関数か、 536|* BLex3_Engine_isPtrEOF 関数で判定できます。 537|***************************************************************************/ 538|char* BLex3_Engine_getOverPtr( BLex3_Engine* m ) 539|{ 540| #if 0 541| return m->eof_first < m->offset_over ? m->eof_first : m->offset_over; 542| #endif 543| 544| return m->eof_first < m->buf_over ? m->eof_first : m->buf_over; 545|} 546| 547| 548|/************************************************************************** 549|* 20. <<< [BLex3_Engine_isPtrEOF] 指定のファイルポインタの位置は EOF かを返す >>> 550|*【引数】 551|* ・BLex3_Engine* m; 字句解析エンジン 552|* ・char* fp; ファイルポインタ 553|* ・bool 返り値; fp は EOF(End of File)かどうか 554|***************************************************************************/ 555|bool BLex3_Engine_isPtrEOF( BLex3_Engine* m, char* fp ) 556|{ 557| return m->eof_first < m->buf_over && fp >= m->eof_first; 558|} 559| 560| 561|/************************************************************************** 562|* 21. <<< [BLex3_Engine_getSJisPtr] Shift Jis 判定バッファにアクセスするポインタを返す >>> 563|*【引数】 564|* ・BLex3_Engine* m; 字句解析エンジン 565|* ・char* 返り値; Shift Jis 判定バッファにアクセスするポインタ 566|*【補足】 567|*・本関数を呼び出す前に、BLex3_Engine_getFiltPtr 関数を呼び出してください。 568|*・返り値を p とすると、*p で現在のファイルポインタの位置のコードタイプ 569|* (BLex3_Ascii など)を参照することができます。*(p+1) で次の位置の 570|* コードタイプを参照することができます。 571|***************************************************************************/ 572|char* BLex3_Engine_getSJisPtr( BLex3_Engine* m ) 573|{ 574| char* fp2; 575| 576| ASSERT( m->sjis_buf != NULL ); 577| 578| fp2 = m->sjis_buf + ( m->fp - m->buf ); 579| 580| #if ! ERRORS_DEBUG_FALSE 581| ASSERT( *fp2 != BLex3_SJisUnknown ); 582| #endif 583| 584| return fp2; 585|} 586| 587| 588|/************************************************************************** 589|* 22. <<< [BLex3_Engine_next] ファイルポインタを進める(バイト数指定) >>> 590|*【引数】 591|* ・BLex3_Engine* m; 字句解析エンジン 592|* ・int n; 進めるバイト数(負の数も可) 593|*【補足】 594|*・本関数を呼び出したら、前に BLex3_Engine_getFilePtr 関数から取得したファイル 595|* ポインタは使えなくなります。再び、BLex3_Engine_getFilePtr 関数を呼び出して、 596|* 新しいファイルポインタを取得してください。 597|***************************************************************************/ 598|void BLex3_Engine_next( BLex3_Engine* m, int n ) 599|{ 600| m->fp += n; 601| m->pos.sjis_type = BLex3_SJisUnknown; /* BLex3_Engine_getFilePtr で本設定 */ 602|} 603| 604|/************************************************************************** 605|* 23. <<< [BLex3_Engine_nextBuf] 内部バッファの次の位置にファイルポインタを移動する >>> 606|*【引数】 607|* ・BLex3_Engine* m; 字句解析エンジン 608|***************************************************************************/ 609|void BLex3_Engine_nextBuf( BLex3_Engine* m ) 610|{ 611| m->fp = m->buf_over; 612|} 613| 614|/************************************************************************** 615|* 24. <<< [BLex3_Engine_nextByPtr] ファイルポインタを進める(アドレス指定) >>> 616|*【引数】 617|* ・BLex3_Engine* m; 字句解析エンジン 618|* ・char* next_fp; ファイルポインタ(→補足) 619|*【補足】 620|*・本関数は、BLex3_Engine_getFilePtr 関数で取得したポインタ fp を進めた 621|* アドレス next_fp = fp + n に m のファイルポインタを合わせます。 622|*・next_fp は、BLex3_Engine_getFilePtr 関数から取得できる内部バッファの 623|* アドレスを指定します。内部バッファの外(前後)を指定しても、その位置に相当する 624|* ファイルアドレスに正しく設定します。 625|***************************************************************************/ 626|void BLex3_Engine_nextByPtr( BLex3_Engine* m, char* next_fp ) 627|{ 628| m->fp = next_fp; 629| m->pos.sjis_type = BLex3_SJisUnknown; 630|} 631| 632|/************************************************************************** 633|* 25. <<< [BLex3_Engine_getPos] ファイルポインタのある位置のファイルアドレスを返す >>> 634|*【引数】 635|* ・BLex3_Engine* m; 字句解析エンジン 636|* ・BLex3_Pos* pos; (出力)ファイルアドレス 637|*【補足】 638|*・BLex3_Engine_getPos2 関数の fp 引数に、BLex3_Engine_getFilePtr 関数の返り値を 639|* そのまま指定したものと同じです。 640|***************************************************************************/ 641|void BLex3_Engine_getPos( BLex3_Engine* m, BLex3_Pos* pos ) 642|{ 643| if ( m->fp - m->buf < 0 ) 644| BLex3_Engine_getFilePtr( m, 0 ); 645| pos->pos = m->pos.pos + (m->fp - m->buf); 646| if ( m->sjis_buf != NULL ) 647| pos->sjis_type = *( m->sjis_buf + (m->fp - m->buf) ); 648|} 649| 650| 651|/************************************************************************** 652|* 26. <<< [BLex3_Engine_getPos0] ファイルポインタのある位置のファイルアドレスを返す >>> 653|*【引数】 654|* ・BLex3_Engine* m; 字句解析エンジン 655|* ・int 返り値; ファイルアドレス 656|*【補足】 657|*・本関数の返り値では、BLex3_Engine_setPos 関数が使えませんが、 658|* BLex3_Pos::pos とファイルアドレスの大小比較ができます。 659|***************************************************************************/ 660|int BLex3_Engine_getPos0( BLex3_Engine* m ) 661|{ 662| return m->pos.pos + (m->fp - m->buf); 663|} 664| 665| 666|/************************************************************************** 667|* 27. <<< [BLex3_Engine_getPos2] ファイルアドレスを返す >>> 668|*【引数】 669|* ・BLex3_Engine* m; 字句解析エンジン 670|* ・char* fp; ファイルポインタ(→補足) 671|* ・BLex3_Pos* pos; (出力)ファイルアドレス 672|*【補足】 673|*・fp は、BLex3_Engine_getFilePtr 関数から取得できる内部バッファの 674|* アドレスを指定します。 675|*・fp の位置に対応するファイルアドレス(ファイルの先頭を0としたオフセット) 676|* を pos に格納します。取得したファイルアドレスは、BLex3_Engine_setPos 関数に使います。 677|***************************************************************************/ 678|void BLex3_Engine_getPos2( BLex3_Engine* m, char* fp, BLex3_Pos* pos ) 679|{ 680| ASSERT( fp >= m->buf ); 681| 682| pos->pos = m->pos.pos + ( fp - m->buf ); 683| if ( fp < m->buf_over ) { 684| pos->sjis_type = *( m->sjis_buf + (fp - m->buf) ); 685| } 686| 687| /* 内部バッファより後のアドレスを返すとき、sjis_type を求める */ 688| else { 689| char* p = m->sjis_buf + (m->buf_over - m->buf) - 1; 690| int n; 691| int c; 692| 693| if ( *p == BLex3_SJisUnknown ) return; 694| 695| /* 内部バッファの直後の文字について */ 696| if ( *p == BLex3_SJisFirst ) { 697| if ( fp == m->buf_over ) { 698| pos->sjis_type = BLex3_SJisSecond; 699| return; 700| } 701| fseek( m->f, pos->pos + 1, SEEK_SET ); 702| n = fp - m->buf_over - 1; 703| } 704| else { 705| fseek( m->f, pos->pos, SEEK_SET ); 706| n = fp - m->buf_over; 707| } 708| 709| /* 内部バッファの直後より後の文字について */ 710| for(;;) { 711| c = fgetc( m->f ); 712| if ( _ismbblead( c ) ) { 713| if ( n == 0 ) 714| { pos->sjis_type = BLex3_SJisFirst; return; } 715| else if ( n == 1 ) 716| { pos->sjis_type = BLex3_SJisSecond; return; } 717| fgetc( m->f ); 718| n--; 719| } 720| else { 721| if ( n == 0 ) 722| { pos->sjis_type = BLex3_Ascii; return; } 723| } 724| n--; 725| } 726| } 727|} 728| 729| 730|/************************************************************************** 731|* 28. <<< [BLex3_Engine_getPos3] ファイルアドレスを返す >>> 732|*【引数】 733|* ・BLex3_Engine* m; 字句解析エンジン 734|* ・int n; 現在のファイルポインタの位置からの相対位置 735|* ・BLex3_Pos* pos; (出力)ファイルアドレス 736|*【補足】 737|*・相対位置が内部バッファの外でも構いません。 738|***************************************************************************/ 739|void BLex3_Engine_getPos3( BLex3_Engine* m, int n, BLex3_Pos* pos ) 740|{ 741| ASSERT( n >= 0 && n < m->buf_over - m->buf ); 742| 743| if ( m->fp + n > m->buf_over ) { 744| BLex3_Pos here; 745| 746| Errors_notSupport(); 747| BLex3_Engine_getPos( m, &here ); 748| BLex3_Engine_next( m, n ); 749| BLex3_Engine_getPos( m, pos ); 750| BLex3_Engine_setPos( m, &here ); /* ファイルポインタがずれる */ 751| } 752| else { 753| if ( m->fp + n == m->buf_over ) 754| BLex3_Engine_getFilePtr( m, n + 1 ); 755| 756| pos->pos = m->pos.pos + ( m->fp - m->buf ) + n; 757| pos->sjis_type = *( m->sjis_buf + (m->fp - m->buf) + n ); 758| } 759|} 760| 761| 762|/************************************************************************** 763|* 29. <<< [BLex3_Engine_getEndPos] ファイルの最後のファイルアドレスを返す >>> 764|*【引数】 765|* ・BLex3_Engine* m; 字句解析エンジン 766|* ・BLex3_Pos* pos; (出力)最後のファイルアドレス 767|***************************************************************************/ 768|void BLex3_Engine_getEndPos( BLex3_Engine* m, BLex3_Pos* pos ) 769|{ 770| fseek( m->f, 0, SEEK_END ); 771| pos->pos = ftell( m->f ); 772| pos->sjis_type = BLex3_SJisUnknown; 773|} 774| 775| 776|/************************************************************************** 777|* 30. <<< [BLex3_Engine_setPos] ファイルポインタを指定のファイルアドレスに移動する >>> 778|*【引数】 779|* ・BLex3_Engine* m; 字句解析エンジン 780|* ・BLex3_Pos* pos; ファイルアドレス 781|*【補足】 782|*・pos は、BLex3_Engine_getPos 関数から取得したものを指定します。 783|*・本関数を使って移動した位置のファイルの内容は、BLex3_Engine_getFilePtr 関数 784|* を使って取得したファイルポインタを使って参照します。 785|***************************************************************************/ 786|void BLex3_Engine_setPos( BLex3_Engine* m, BLex3_Pos* pos ) 787|{ 788| ASSERT( pos->pos != BLex3_nullPos.pos ); 789| 790| m->fp = m->buf + ( pos->pos - m->pos.pos ); 791| m->pos.sjis_type = pos->sjis_type; 792|} 793| 794| 795|/************************************************************************** 796|* 31. <<< [BLex3_Engine_setPos2] ファイルポインタを移動する(相対位置指定) >>> 797|*【引数】 798|* ・BLex3_Engine* m; 字句解析エンジン 799|* ・BLex3_Pos* pos; ファイルアドレス 800|* ・int n; pos からの相対位置(0以上) 801|***************************************************************************/ 802|void BLex3_Engine_setPos2( BLex3_Engine* m, BLex3_Pos* pos, int n ) 803|{ 804| bool f = ( pos->pos < m->pos.pos ); 805| 806| BLex3_Engine_setPos( m, pos ); 807| if ( f && m->sjis_buf != NULL ) 808| BLex3_Engine_getFilePtr( m, 0 ); 809| BLex3_Engine_next( m, n ); 810|} 811| 812| 813|/************************************************************************** 814|* 32. <<< [BLex3_Engine_copy] 入力ファイルの一部をそのままファイルに出力する >>> 815|*【引数】 816|* ・BLex3_Engine* m; 字句解析エンジン 817|* ・FILE* out; 出力ファイル 818|* ・BLex3_Pos* start; 出力を開始する入力ファイルのアドレス 819|* ・BLex3_Pos* over; 最後の出力をする入力ファイルのアドレスの次 820|***************************************************************************/ 821|#if 0 822|void BLex3_Engine_copy( BLex3_Engine* m, FILE* out, 823| BLex3_Pos* start, BLex3_Pos* over ) 824|{ 825| char* p = m->buf + ( start->pos - m->pos.pos ); 826| int overPos = m->pos.pos + ( m->buf_over - m->buf ); 827| int c; 828| char* cp; 829| 830| ASSERT( start->pos <= over->pos ); 831| 832| BLex3_Engine_setPos( m, start ); 833| while ( overPos < over->pos ) { 834| fputs( p, out ); 835| BLex3_Engine_nextBuf( m ); 836| p = BLex3_Engine_getFilePtr( m, 0 ); 837| if ( p == NULL ) return; 838| overPos = m->pos.pos + ( m->buf_over - m->buf ); 839| } 840| cp = m->buf + ( over->pos - m->pos.pos ); 841| c = *cp; 842| *cp = '\0'; 843| fputs( p, out ); 844| *cp = c; 845|} 846|#endif 847| 848| 849|/*---------------------------------------------------------------------*/ 850|/* 33. <<<◆(BLex3_EngineU) 字句解析エンジン・ユーティリティ >>> */ 851|/*---------------------------------------------------------------------*/ 852| 853|void BLex3_EngineU_writeHTML_sub( char* data, char* data_over, int* iLine, 854| FILE* out ); 855|void BLex3_EngineU_getStr_sub( char* fp, char* fp_over, 856| char** ps, int* ps_size ); 857| 858|/************************************************************************** 859|* 34. <<< [BLex3_EngineU_readWord] 指定の区切り文字が現れるまで読み込む >>> 860|*【引数】 861|* ・BLex3_EngineU* m; 字句解析エンジン・ユーティリティ 862|* ・char* s; 読込んだデータを格納する領域の先頭アドレス 863|* ・int s_size; s の領域のサイズ 864|* ・char* terms; 区切り文字の並び 865|* ・bool bDQ; ダブルクォーテーションで囲むものを有効にするかどうか 866|*【補足】 867|*・現在のファイルポインタの位置(BLex3_Engine_getFilePtr で取得できるアドレス) 868|* から区切り文字(またはファイルの最後、または s_size)までを s に読み込みます。 869|*・s の最後は、'\0'文字が格納されます。 870|*・現在のファイルポインタの位置が " のとき、かつ bDQ が true のとき、 871|* terms に関係無く、"" で囲まれた部分を読み込みます。 872|*・本関数を実行したら、現在のファイルポインタの位置が、区切り文字のある 873|* 位置(または、ファイルの最後)に移動します。 874|***************************************************************************/ 875|void BLex3_EngineU_readWord( BLex3_EngineU* m, 876| char* s, int s_size, const char* terms, bool bDQ ) 877|{ 878| char* fp; 879| char* p; 880| const char* dq = "\""; 881| ArrX_Buf s_buf; 882| 883| ArrX_Buf_init( &s_buf, s, s_size ); 884| ArrX_Buf_addStr( &s_buf, "" ); 885| 886| fp = BLex3_Engine_getFilePtr( &m->inherit_BLex3_Engine, 0 ); 887| if ( bDQ && *fp == '\"' ) { 888| terms = dq; 889| BLex3_Engine_next( &m->inherit_BLex3_Engine, 1 ); 890| fp = BLex3_Engine_getFilePtr( &m->inherit_BLex3_Engine, 0 ); 891| } 892| 893| while ( fp != NULL ) { 894| 895| p = StrX_strchrs( fp, terms ); 896| for (;;) { 897| 898| /* 次のバッファへ: to next buffer */ 899| if ( p == NULL ) { 900| ArrX_Buf_addMem( &s_buf, fp, 901| BLex3_Engine_getOverPtr( &m->inherit_BLex3_Engine ) - fp ); 902| BLex3_Engine_nextBuf( &m->inherit_BLex3_Engine ); 903| fp = BLex3_Engine_getFilePtr( &m->inherit_BLex3_Engine, 0 ); 904| break; 905| } 906| 907| /* "" で囲まれた文字列中に " が連続していたとき: case of "" in "" */ 908| else if ( terms == dq && *p == '\"' && *(p + 1) == '\"' ) 909| p = StrX_strchrs( p + 2, terms ); 910| 911| /* 区切り文字が見つかったとき: case of find term char */ 912| else 913| goto exit_while; 914| } 915| } 916| exit_while: 917| 918| ArrX_Buf_addMem( &s_buf, fp, p - fp ); 919| ArrX_Buf_addChr( &s_buf, '\0' ); 920| if ( fp != NULL ) { 921| if ( terms == dq ) p++; 922| BLex3_Engine_nextByPtr( &m->inherit_BLex3_Engine, p ); 923| } 924|} 925| 926| 927|/************************************************************************** 928|* 35. <<< [BLex3_EngineU_skip] 指定の文字をスキップし続ける >>> 929|*【引数】 930|* ・BLex3_EngineU* m; 字句解析エンジン・ユーティリティ 931|* ・char* skipChars; スキップする文字を並べた文字列 932|*【補足】 933|*・現在のファイルポインタの位置(BLex3_Engine_getFilePtr で取得できるアドレス) 934|* から skipChars に含まれる(半角)文字をスキップして、現在のファイルポインタの 935|* 位置を進めます。 936|*【例】 937|* BLex3_EngineU_skip( &eng, " \t\r\n" ); // 空白とタブと改行をスキップ 938|***************************************************************************/ 939|void BLex3_EngineU_skip( BLex3_EngineU* m, const char* skipChars ) 940|{ 941| BLex3_Engine* eng = &m->inherit_BLex3_Engine; 942| char* fp; 943| char* p; 944| 945| for (;;) { 946| fp = BLex3_Engine_getFilePtr( eng, 0 ); 947| if ( fp == NULL ) return; 948| p = StrX_strchrs_not( fp, skipChars ); 949| if ( p != NULL ) break; 950| BLex3_Engine_nextBuf( eng ); 951| } 952| BLex3_Engine_nextByPtr( eng, p ); 953|} 954| 955| 956|/************************************************************************** 957|* 36. <<< [BLex3_EngineU_skipTo] 指定の文字までスキップし続ける >>> 958|*【引数】 959|* ・BLex3_EngineU* m; 字句解析エンジン・ユーティリティ 960|* ・char* terms; スキップを止める文字を並べた文字列 961|* ・int plus; terms に含まれる文字のある位置からずらす量 962|*【補足】 963|*・現在のファイルポインタの位置(BLex3_Engine_getFilePtr で取得できるアドレス) 964|* から terms に含まれる(半角)文字までスキップして、現在のファイルポインタの 965|* 位置を進めます。 966|*・plus に +1 を指定すると、terms に含まれる文字の次の位置に、現在の 967|* ファイルポインタの位置を進めます。 968|*【例】 969|* BLex3_EngineU_skipTo( &eng, "\n", 1 ); // 次の行までスキップする 970|***************************************************************************/ 971|void BLex3_EngineU_skipTo( BLex3_EngineU* m, const char* terms, int plus ) 972|{ 973| BLex3_Engine* eng = &m->inherit_BLex3_Engine; 974| char* fp; 975| char* fp2; 976| char* p; 977| 978| for (;;) { 979| fp = BLex3_Engine_getFilePtr( eng, 2 ); 980| if ( fp == NULL ) return; 981| fp2 = BLex3_Engine_getSJisPtr( eng ); 982| if ( *fp2 == BLex3_SJisSecond ) fp++; 983| p = StrX_strchrs2( fp, terms ); 984| if ( p != NULL ) break; 985| BLex3_Engine_nextBuf( eng ); 986| } 987| BLex3_Engine_nextByPtr( eng, p + plus ); 988|} 989| 990| 991|/************************************************************************** 992|* 37. <<< [BLex3_EngineU_skipToStr] 指定の文字列までスキップし続ける >>> 993|*【引数】 994|* ・BLex3_EngineU* m; 字句解析エンジン・ユーティリティ 995|* ・char* term; スキップを止める文字を並べた文字列 996|* ・int plus; term に含まれる文字のある位置からずらす量 997|* ・bool bCase; 大文字小文字を区別するかどうか 998|*【補足】 999|*・現在のファイルポインタの位置(BLex3_Engine_getFilePtr で取得できるアドレス) 1000|* から term に一致する位置までスキップして、現在のファイルポインタの位置を進めます。 1001|*・plus に +1 を指定すると、term に一致する先頭の位置の次の位置に、現在の 1002|* ファイルポインタの位置を進めます。 1003|*【例】 1004|* BLex3_EngineU_skipToStr( &eng, "end", 3, false ); // end の次までスキップする 1005|***************************************************************************/ 1006|void BLex3_EngineU_skipToStr( BLex3_EngineU* m, const char* term, int plus, 1007| bool bCase ) 1008|{ 1009| BLex3_Engine* eng = &m->inherit_BLex3_Engine; 1010| const int term_len = strlen( term ); 1011| char* fp; 1012| char* p; 1013| int hittingCount = 0; 1014| 1015| for (;;) { 1016| fp = BLex3_Engine_getFilePtr( eng, term_len ); 1017| p = StrX_stristr3( fp, term, bCase, &hittingCount ); 1018| if ( p != NULL ) break; 1019| BLex3_Engine_nextBuf( eng ); 1020| } 1021| BLex3_Engine_nextByPtr( eng, p + plus ); 1022|} 1023| 1024| 1025|/************************************************************************** 1026|* 38. <<< [BLex3_EngineU_skipTag] HTML のタグをスキップする >>> 1027|*【引数】 1028|* ・BLex3_EngineU* m; 字句解析エンジン・ユーティリティ 1029|***************************************************************************/ 1030|void BLex3_EngineU_skipTag( BLex3_EngineU* m ) 1031|{ 1032| char* fp; 1033| char* fp_over; 1034| 1035| fp = BLex3_Engine_getFilePtr( &m->inherit_BLex3_Engine, 4 ); 1036| fp_over = BLex3_Engine_getOverPtr( &m->inherit_BLex3_Engine ); 1037| 1038| ASSERT( *fp == '<' ); 1039| 1040| if ( strncmp( fp + 1, "!--", 3 ) == 0 ) { 1041| BLex3_EngineU_skipToStr( m, "-->", +3, true ); 1042| } 1043| else { 1044| BLex3_EngineU_skipTo( m, ">", +1 ); 1045| } 1046|} 1047| 1048|/************************************************************************** 1049|* 39. <<< [BLex3_EngineU_write] 指定の範囲をファイルに出力する >>> 1050|*【引数】 1051|* ・BLex3_EngineU* m; 字句解析エンジン・ユーティリティ 1052|* ・BLex3_Pos* firstPos; 出力開始位置 1053|* ・BLex3_Pos* overPos; 出力終了の次の位置 1054|* ・FILE* out; 出力ファイル 1055|*【補足】 1056|*・本関数を呼び出したら、BLex3_Engine_setPos 関数と BLex3_Engine_getFilePtr 1057|* 関数を呼び出して、ファイルポインタの位置を再取得してください。 1058|***************************************************************************/ 1059|void BLex3_EngineU_write( BLex3_EngineU* m, BLex3_Pos* firstPos, 1060| BLex3_Pos* overPos, FILE* out ) 1061|{ 1062| BLex3_Engine* eng = &m->inherit_BLex3_Engine; 1063| char* fp; 1064| char* fp_over; 1065| BLex3_Pos pos; 1066| 1067| ASSERT( firstPos->pos <= overPos->pos ); 1068| 1069| BLex3_Engine_setPos( eng, firstPos ); 1070| for (;;) { 1071| fp = BLex3_Engine_getFilePtr( eng, 0 ); 1072| fp_over = BLex3_Engine_getOverPtr( eng ); 1073| BLex3_Engine_getPos2( eng, fp_over, &pos ); 1074| if ( overPos->pos > pos.pos ) { 1075| fwrite( fp, fp_over - fp, 1, out ); 1076| BLex3_Engine_nextBuf( eng ); 1077| } 1078| else { 1079| fp_over = BLex3_Engine_getFilePtrByPos( eng, overPos->pos ); 1080| fwrite( fp, fp_over - fp, 1, out ); 1081| return; 1082| } 1083| } 1084|} 1085| 1086| 1087|/************************************************************************** 1088|* 40. <<< [BLex3_EngineU_writeHTML] 指定の範囲のテキストを HTML ファイルに出力する >>> 1089|*【引数】 1090|* ・BLex3_EngineU* m; 字句解析エンジン・ユーティリティ 1091|* ・BLex3_Pos* firstPos; 出力開始位置 1092|* ・BLex3_Pos* overPos; 出力終了の次の位置 1093|* ・int iLine; 出力開始位置の行番号(-1で行番号を出力しない) 1094|* ・FILE* out; 出力ファイル 1095|*【補足】 1096|*・<, >, & を <, >, & に変換します。 1097|*・行番号を出力します。 1098|*・特定のタグをそのまま出力するときは、HtmlPars を使って特定のタグを判定し、 1099|* BLex3_EngineU_write 関数でファイルに出力します。 1100|***************************************************************************/ 1101|void BLex3_EngineU_writeHTML( BLex3_EngineU* m, BLex3_Pos* firstPos, 1102| BLex3_Pos* overPos, int iLine, FILE* out ) 1103|{ 1104| BLex3_Engine* eng = &m->inherit_BLex3_Engine; 1105| char* fp; 1106| char* fp_over; 1107| BLex3_Pos pos; 1108| 1109|//COUNT(12469) 1110|//BK 1111| 1112| ASSERT( firstPos->pos <= overPos->pos ); 1113| if ( firstPos->pos == overPos->pos ) return; 1114| 1115| BLex3_Engine_setPos( eng, firstPos ); 1116| for (;;) { 1117| fp = BLex3_Engine_getFilePtr( eng, 0 ); 1118| fp_over = BLex3_Engine_getOverPtr( eng ); 1119| BLex3_Engine_getPos2( eng, fp_over, &pos ); 1120| if ( overPos->pos > pos.pos ) { 1121| BLex3_EngineU_writeHTML_sub( fp, fp_over, &iLine, out ); 1122| BLex3_Engine_nextBuf( eng ); 1123| } 1124| else { 1125| fp_over = BLex3_Engine_getFilePtrByPos( eng, overPos->pos ); 1126| BLex3_EngineU_writeHTML_sub( fp, fp_over, &iLine, out ); 1127| return; 1128| } 1129| } 1130|} 1131| 1132| 1133|/************************************************************************** 1134|* 41. <<< [BLex3_EngineU_writeHTML_sub] テキストデータを HTML ファイルに出力する >>> 1135|*【引数】 1136|* ・char* data; 出力するテキストファイルの内容の先頭アドレス 1137|* ・char* data_over; 同、末尾の次のアドレス 1138|* ・int* piLine; (入力)data の行番号、(出力)data_over の行番号 1139|* ・FILE* out; 出力ファイル 1140|*【補足】 1141|*・BLex3_EngineU_writeHTML のサブルーチンです。 1142|***************************************************************************/ 1143|void BLex3_EngineU_writeHTML_sub( char* data, char* data_over, int* piLine, 1144| FILE* out ) 1145|{ 1146| char* p; 1147| char* tp = data; /* そのまま出力する先頭 */ 1148| int iLine = *piLine; 1149| 1150| for ( p = data; p < data_over; p++ ) { 1151| switch ( *p ) { 1152| case '<': 1153| fwrite( tp, p - tp, 1, out ); tp = p + 1; 1154| fputs( "<", out ); 1155| break; 1156| case '>': 1157| fwrite( tp, p - tp, 1, out ); tp = p + 1; 1158| fputs( ">", out ); 1159| break; 1160| case '&': 1161| fwrite( tp, p - tp, 1, out ); tp = p + 1; 1162| fputs( "&", out ); 1163| break; 1164| case '\n': 1165| if ( iLine != -1 ) { 1166| fwrite( tp, p - tp, 1, out ); tp = p + 1; 1167| iLine ++; 1168| fprintf( out, "\n%4d|", iLine ); 1169| } 1170| break; 1171| } 1172| } 1173| fwrite( tp, p - tp, 1, out ); 1174| *piLine = iLine; 1175|} 1176| 1177|/************************************************************************** 1178|* 42. <<< [BLex3_EngineU_writeNoTag] HTML タグを除いた HTML をテキストファイルに出力する >>> 1179|*【引数】 1180|* ・BLex3_EngineU* m; 字句解析エンジン・ユーティリティ 1181|* ・BLex3_Pos* firstPos; 出力開始位置 1182|* ・BLex3_Pos* overPos; 出力終了の次の位置 1183|* ・FILE* out; 出力ファイル 1184|*【補足】 1185|*・firstPos から overPos までの HTML テキストから <, > で囲まれた HTML タグを 1186|* カットして、テキストファイルに出力します。 1187|*・firstPos から overPos までの先頭または末尾の空白、タブ、改行もカットします。 1188|***************************************************************************/ 1189|void BLex3_EngineU_writeNoTag( BLex3_EngineU* m, BLex3_Pos* firstPos, 1190| BLex3_Pos* overPos, FILE* out ) 1191|{ 1192| BLex3_Engine* eng = &m->inherit_BLex3_Engine; 1193| char* fp; 1194| char* fp_over; 1195| char* fp_writeOver; 1196| bool bSpc; /* 空白、タブ、改行、HTML タグが続いているかどうか */ 1197| BLex3_Pos topPos; 1198| BLex3_Pos pos; 1199| int c; 1200| 1201| ASSERT( firstPos->pos <= overPos->pos ); 1202| 1203| /* 最初の空白や HTML タグをスキップする */ 1204| BLex3_Engine_setPos( eng, firstPos ); 1205| fp = BLex3_Engine_getFilePtr( eng, 0 ); 1206| fp_over = BLex3_Engine_getOverPtr( eng ); 1207| 1208| for (;;) { 1209| c = *fp; 1210| if ( c == ' ' || c == '\t' || c == '\r' || c == '\n' ) { 1211| fp++; 1212| if ( fp == fp_over ) { 1213| BLex3_Engine_nextBuf( eng ); 1214| fp = BLex3_Engine_getFilePtr( eng, 0 ); 1215| fp_over = BLex3_Engine_getOverPtr( eng ); 1216| } 1217| } 1218| else if ( c == '<' ) { 1219| BLex3_Engine_nextByPtr( eng, fp ); 1220| BLex3_EngineU_skipTag( m ); 1221| fp = BLex3_Engine_getFilePtr( eng, 0 ); 1222| fp_over = BLex3_Engine_getOverPtr( eng ); 1223| } 1224| else 1225| break; 1226| } 1227| fp_writeOver = BLex3_Engine_getFilePtrByPos2( eng, overPos->pos ); 1228| if ( fp_writeOver < fp_over ) fp_over = fp_writeOver; 1229| 1230| /* 末尾の空白や HTML タグの前までファイルに出力する */ 1231| bSpc = false; 1232| BLex3_Engine_getPos2( eng, fp, &topPos ); 1233| 1234| for (;;) { 1235| c = *fp; 1236| if ( c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '<' ) { 1237| 1238| /* 空白などが始まったら、それまでを出力する */ 1239| if ( ! bSpc ) { 1240| BLex3_Engine_getPos2( eng, fp, &pos ); 1241| BLex3_EngineU_write( m, &topPos, &pos, out ); 1242| 1243| BLex3_Engine_setPos( eng, &pos ); 1244| fp = BLex3_Engine_getFilePtr( eng, 0 ); 1245| fp_over = BLex3_Engine_getOverPtr( eng ); 1246| fp_writeOver = BLex3_Engine_getFilePtrByPos2( eng, overPos->pos ); 1247| if ( fp_writeOver < fp_over ) fp_over = fp_writeOver; 1248| 1249| BLex3_Pos_copy( &topPos, &pos ); 1250| bSpc = true; 1251| } 1252| 1253| /* タグをスキップする */ 1254| if ( c == '<' ) { 1255| BLex3_Engine_nextByPtr( eng, fp ); 1256| BLex3_EngineU_skipTag( m ); 1257| BLex3_Engine_getPos( eng, &topPos ); 1258| fp = BLex3_Engine_getFilePtr( eng, 0 ); 1259| fp_over = BLex3_Engine_getOverPtr( eng ); 1260| fp_writeOver = BLex3_Engine_getFilePtrByPos2( eng, overPos->pos ); 1261| if ( fp_writeOver < fp_over ) fp_over = fp_writeOver; 1262| } 1263| else 1264| fp++; 1265| } 1266| else { 1267| bSpc = false; 1268| fp++; 1269| } 1270| 1271| /* fp が内部バッファを超えたら更新する */ 1272| if ( fp >= fp_over ) { 1273| if ( fp >= fp_writeOver ) { 1274| break; 1275| } 1276| BLex3_Engine_nextBuf( eng ); 1277| fp = BLex3_Engine_getFilePtr( eng, 0 ); 1278| fp_over = BLex3_Engine_getOverPtr( eng ); 1279| fp_writeOver = BLex3_Engine_getFilePtrByPos2( eng, overPos->pos ); 1280| if ( fp_writeOver < fp_over ) fp_over = fp_writeOver; 1281| } 1282| } 1283| 1284| /* 最後が空白でなかったら、最後まで出力する */ 1285| if ( ! bSpc ) { 1286| BLex3_EngineU_write( m, &topPos, overPos, out ); 1287| } 1288|} 1289| 1290| 1291|/************************************************************************** 1292|* 43. <<< [BLex3_EngineU_getStr] 指定の範囲を文字列として取得する >>> 1293|*【引数】 1294|* ・BLex3_EngineU* m; 字句解析エンジン・ユーティリティ 1295|* ・BLex3_Pos* firstPos; 出力開始位置 1296|* ・BLex3_Pos* overPos; 出力終了の次の位置 1297|* ・char* s; 文字列を格納する領域の先頭アドレス 1298|* ・int s_size; s のサイズ 1299|***************************************************************************/ 1300|void BLex3_EngineU_getStr( BLex3_EngineU* m, BLex3_Pos* firstPos, 1301| BLex3_Pos* overPos, char* s, int s_size ) 1302|{ 1303| BLex3_Engine* eng = &m->inherit_BLex3_Engine; 1304| char* fp; 1305| char* fp_over; 1306| BLex3_Pos pos; 1307| 1308| ASSERT( firstPos->pos <= overPos->pos ); 1309| 1310| BLex3_Engine_setPos( eng, firstPos ); 1311| for (;;) { 1312| fp = BLex3_Engine_getFilePtr( eng, 0 ); 1313| fp_over = BLex3_Engine_getOverPtr( eng ); 1314| BLex3_Engine_getPos2( eng, fp_over, &pos ); 1315| if ( overPos->pos > pos.pos ) { 1316| BLex3_EngineU_getStr_sub( fp, fp_over, &s, &s_size ); 1317| if ( s_size <= 0 ) return; 1318| BLex3_Engine_nextBuf( eng ); 1319| } 1320| else { 1321| fp_over = BLex3_Engine_getFilePtrByPos( eng, overPos->pos ); 1322| BLex3_EngineU_getStr_sub( fp, fp_over, &s, &s_size ); 1323| return; 1324| } 1325| } 1326|} 1327| 1328| 1329|/************************************************************************** 1330|* 44. <<< [BLex3_EngineU_getStr_sub] テキストデータを文字列として取得する >>> 1331|*【引数】 1332|* ・char* fp; 出力するテキストファイルの内容の先頭アドレス 1333|* ・char* fp_over; 同、末尾の次のアドレス 1334|* ・char* ps; (入力)取得領域のアドレス、(出力)次の取得アドレス 1335|* ・int* ps_size; (入力)取得領域のサイズ、(出力)残りのサイズ 1336|*【補足】 1337|*・BLex3_EngineU_getStr のサブルーチンです。 1338|***************************************************************************/ 1339|void BLex3_EngineU_getStr_sub( char* fp, char* fp_over, 1340| char** ps, int* ps_size ) 1341|{ 1342| char* s = *ps; 1343| int s_size_1 = *ps_size - 1; 1344| int f_size = fp_over - fp; 1345| 1346| if ( f_size < s_size_1 ) { 1347| memcpy( s, fp, f_size ); 1348| s[f_size] = '\0'; 1349| *ps = s + f_size; 1350| (*ps_size) -= f_size; 1351| } 1352| else { 1353| memcpy( s, fp, s_size_1 ); 1354| s[s_size_1] = '\0'; 1355| *ps = s + s_size_1; 1356| (*ps_size) -= s_size_1; 1357| } 1358|} 1359| 1360|/*---------------------------------------------------------------------*/ 1361|/* 45. <<<◆(BLex3_Parser) パーサ >>> */ 1362|/*---------------------------------------------------------------------*/ 1363| 1364| 1365|/*********************************************************************** 1366|* 46. <<< BLex3_Parser インターフェイス・関数定義 >>> 1367|************************************************************************/ 1368|#ifndef NDEBUG 1369|INF_FUNC_0( BLex3_Parser, finish, void, BLex3_Parser_finish, BLex3_Parser, t ); 1370|INF_FUNC_1( BLex3_Parser, linkEngine, void, BLex3_Parser_setEngine, BLex3_Parser, BLex3_Engine*, t,a ); 1371|INF_FUNC_0( BLex3_Parser, parse, void, BLex3_Parser_parse, BLex3_Parser, t ); 1372|INF_FUNC_R0( BLex3_Parser, getTokenType, int, BLex3_Parser_getTokenType, BLex3_Parser, t ); 1373|INF_FUNC_1( BLex3_Parser, getNextParsePos, void, BLex3_Parser_getNextParsePos, BLex3_Parser, BLex3_Pos*, t,a ); 1374|INF_FUNC_0( BLex3_Parser, printLastMsg, void, BLex3_Parser_printLastMsg, BLex3_Parser, t ); 1375|#endif 1376| 1377| 1378|