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; ディスクのセクタサイズ(1024など)
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| m->pos.pos += (m->fp - offset) - m->buf;
375| ASSERT( m->pos.pos >= 0 );
376| fseek( m->f, m->pos.pos, SEEK_SET );
377|
378| readAdr = m->buf;
379| count = (m->buf_over - m->buf) >> m->sec_sft;
380| result = fread( readAdr, m->sec_size, count, m->f );
381| if ( result == 0 ) {
382| fseek( m->f, m->pos.pos + offset, SEEK_SET ); /* for next feof */
383| fgetc( m->f ); /* for next feof */
384| }
385| if ( result == 0 && feof( m->f ) ) {
386| m->fp = m->buf + offset;
387| m->eof_first = m->buf + offset;
388| return NULL;
389| }
390| else if ( result < count ) {
391| fseek( m->f, 0, SEEK_END );
392| m->eof_first = m->buf + ( ftell( m->f ) - m->pos.pos );
393| if ( m->sjis_buf != NULL ) {
394| BLex3_Engine_fillSJisBuf( m, readAdr, m->eof_first,
395| m->pos.sjis_type );
396| }
397| }
398| else {
399| m->eof_first = m->buf_over;
400| if ( m->sjis_buf != NULL /*&& result > 0*/ ) { /* BLEX3_USES_OLD_010831 */
401| BLex3_Engine_fillSJisBuf( m, readAdr,
402| readAdr + (result << m->sec_sft), m->pos.sjis_type );
403| }
404| }
405| m->fp = m->buf + offset;
406| ASSERT( m->fp + offsetOver <= m->buf_over );
407|
408| if ( offsetOver == 0 ) m->offset_over = m->buf_over;
409| else m->offset_over = m->fp + offsetOver;
410| return m->fp;
411| }
412|
413| /* offsetOver までアクセスできないときは、内部バッファをスクロールする */
414| if ( m->fp + offsetOver > m->buf_over || m->fp >= m->buf_over ) {
415| char* fp0 = m->fp - offset;
416| int sjis_type = BLex3_Ascii;
417| int seekPos;
418|
419| /* 内部バッファの外を読みこむとき */
420| if ( fp0 >= m->buf_over ) {
421| seekPos = (fp0 - m->buf) + m->pos.pos;
422| fseek( m->f, seekPos, SEEK_SET );
423| if ( fp0 >= m->buf_over + m->sec_size ) {
424| sjis_type = m->pos.sjis_type;
425| }
426| else {
427| if ( m->sjis_buf != NULL )
428| sjis_type = *( m->sjis_buf + (m->buf_over - m->buf) - 1 );
429| }
430| readAdr = m->buf;
431| count = (m->buf_over - m->buf) >> m->sec_sft;
432| }
433| /* 内部バッファの一部をスクロールするとき */
434| else {
435| memmove( m->buf, fp0, m->buf_over - fp0 );
436| memmove( m->sjis_buf, m->sjis_buf + (fp0 - m->buf), m->buf_over - fp0 );
437| seekPos = m->pos.pos + (m->buf_over - m->buf);
438| fseek( m->f, seekPos, SEEK_SET );
439| readAdr = m->buf + (m->buf_over - fp0);
440| count = (fp0 - m->buf) >> m->sec_sft;
441| if ( m->sjis_buf != NULL )
442| sjis_type = *( m->sjis_buf + (fp0 - m->buf) - 1 );
443| }
444|
445| /* 読みこむ */
446| result = fread( readAdr, m->sec_size, count, m->f );
447| if ( result == 0 ) {
448| fseek( m->f, seekPos, SEEK_SET ); fgetc( m->f ); /* for next feof */
449| }
450| if ( m->sjis_buf != NULL && ! feof(m->f) ) {
451| if ( sjis_type != BLex3_SJisUnknown ) {
452| if ( sjis_type == BLex3_SJisFirst )
453| sjis_type = BLex3_SJisSecond;
454| else
455| sjis_type = _ismbblead( *readAdr ) ? BLex3_SJisFirst : BLex3_Ascii;
456| }
457| BLex3_Engine_fillSJisBuf( m, readAdr,
458| readAdr + (result << m->sec_sft), sjis_type );
459| }
460| m->pos.pos += fp0 - m->buf;
461|
462| /* EOF より後は、'\0' を埋め、m->eof_first を設定する */
463| if ( result < count ) {
464| int fSizeOfs;
465|
466| if ( m->eof_first < m->buf_over ) {
467| m->eof_first -= m->fp - offset - m->buf;
468| memset( readAdr, 0, m->buf_over - readAdr );
469| }
470| else {
471| fseek( m->f, 0, SEEK_END );
472| fSizeOfs = ftell( m->f ) % m->sec_size;
473| m->eof_first = readAdr + (result << m->sec_sft) + fSizeOfs;
474| BLex3_Engine_fillSJisBuf( m, readAdr, m->eof_first, sjis_type );
475| memset( m->eof_first, 0, m->sec_size - fSizeOfs );
476| }
477| }
478| else
479| m->eof_first = m->buf_over;
480|
481| m->fp = m->buf + offset;
482| if ( offsetOver == 0 ) m->offset_over = m->buf_over;
483| else m->offset_over = m->fp + offsetOver;
484| return ( m->fp >= m->eof_first ) ? NULL : m->fp;
485| }
486|
487| /* 読みこむ必要が無いとき */
488| else {
489| if ( offsetOver == 0 ) m->offset_over = m->buf_over;
490| else m->offset_over = m->fp + offsetOver;
491| return ( m->fp >= m->eof_first ) ? NULL : m->fp;
492| }
493|}
494|
495|
496|/**************************************************************************
497|* 17. <<< [BLex3_Engine_getFilePtrByPos] アクセス用ファイルポインタを取得する >>>
498|*【引数】
499|* ・BLex3_Engine* m; 字句解析エンジン
500|* ・long pos; ファイル・アドレス
501|* ・char* 返り値; ファイルポインタ
502|*【補足】
503|*・pos に内部バッファの外(末尾の次を除く)に相当するアドレスは指定できません。
504|***************************************************************************/
505|char* BLex3_Engine_getFilePtrByPos( BLex3_Engine* m, long pos )
506|{
507| char* fp = m->buf + ( pos - m->pos.pos );
508|
509| ASSERT( fp >= m->buf && fp <= m->buf_over );
510|
511| return fp;
512|}
513|
514|/**************************************************************************
515|* 18. <<< [BLex3_Engine_getFilePtrByPos2] アクセス用ファイルポインタを取得する >>>
516|*【補足】
517|*・pos に内部バッファの外が指定できる BLex3_Engine_getFilePtrByPos 関数です。
518|* ただし、ASSERT に引っかからないだけで、内部バッファの外の場合、
519|* 返り値のファイルポインタを使って、ファイルの内容にアクセスできません。
520|* ファイルポインタの位置の比較のために使います。
521|***************************************************************************/
522|char* BLex3_Engine_getFilePtrByPos2( BLex3_Engine* m, long pos )
523|{
524| return m->buf + ( pos - m->pos.pos );
525|}
526|
527|/**************************************************************************
528|* 19. <<< [BLex3_Engine_getOverPtr] 内部バッファに入っている最後のデータの次のアドレスを返す >>>
529|*【引数】
530|* ・BLex3_Engine* m; 字句解析エンジン
531|* ・char* 返り値; アクセスできる領域の次のアドレス
532|*【補足】
533|*・返り値は、内部バッファのサイズや、ファイルの末尾を考慮しています。
534|*・EOF(EndOfFile)かどうかは、BLex3_Engine_getFilePtr 関数か、
535|* BLex3_Engine_isPtrEOF 関数で判定できます。
536|***************************************************************************/
537|char* BLex3_Engine_getOverPtr( BLex3_Engine* m )
538|{
539| #if 0
540| return m->eof_first < m->offset_over ? m->eof_first : m->offset_over;
541| #endif
542|
543| return m->eof_first < m->buf_over ? m->eof_first : m->buf_over;
544|}
545|
546|
547|/**************************************************************************
548|* 20. <<< [BLex3_Engine_isPtrEOF] 指定のファイルポインタの位置は EOF かを返す >>>
549|*【引数】
550|* ・BLex3_Engine* m; 字句解析エンジン
551|* ・char* fp; ファイルポインタ
552|* ・bool 返り値; fp は EOF(End of File)かどうか
553|***************************************************************************/
554|bool BLex3_Engine_isPtrEOF( BLex3_Engine* m, char* fp )
555|{
556| return m->eof_first < m->buf_over && fp >= m->eof_first;
557|}
558|
559|
560|/**************************************************************************
561|* 21. <<< [BLex3_Engine_getSJisPtr] Shift Jis 判定バッファにアクセスするポインタを返す >>>
562|*【引数】
563|* ・BLex3_Engine* m; 字句解析エンジン
564|* ・char* 返り値; Shift Jis 判定バッファにアクセスするポインタ
565|*【補足】
566|*・本関数を呼び出す前に、BLex3_Engine_getFiltPtr 関数を呼び出してください。
567|*・返り値を p とすると、*p で現在のファイルポインタの位置のコードタイプ
568|* (BLex3_Ascii など)を参照することができます。*(p+1) で次の位置の
569|* コードタイプを参照することができます。
570|***************************************************************************/
571|char* BLex3_Engine_getSJisPtr( BLex3_Engine* m )
572|{
573| char* fp2;
574|
575| ASSERT( m->sjis_buf != NULL );
576|
577| fp2 = m->sjis_buf + ( m->fp - m->buf );
578|
579| #if ! ERRORS_DEBUG_FALSE
580| ASSERT( *fp2 != BLex3_SJisUnknown );
581| #endif
582|
583| return fp2;
584|}
585|
586|
587|/**************************************************************************
588|* 22. <<< [BLex3_Engine_next] ファイルポインタを進める(バイト数指定) >>>
589|*【引数】
590|* ・BLex3_Engine* m; 字句解析エンジン
591|* ・int n; 進めるバイト数(負の数も可)
592|*【補足】
593|*・本関数を呼び出したら、前に BLex3_Engine_getFilePtr 関数から取得したファイル
594|* ポインタは使えなくなります。再び、BLex3_Engine_getFilePtr 関数を呼び出して、
595|* 新しいファイルポインタを取得してください。
596|***************************************************************************/
597|void BLex3_Engine_next( BLex3_Engine* m, int n )
598|{
599| m->fp += n;
600| m->pos.sjis_type = BLex3_SJisUnknown; /* BLex3_Engine_getFilePtr で本設定 */
601|}
602|
603|/**************************************************************************
604|* 23. <<< [BLex3_Engine_nextBuf] 内部バッファの次の位置にファイルポインタを移動する >>>
605|*【引数】
606|* ・BLex3_Engine* m; 字句解析エンジン
607|***************************************************************************/
608|void BLex3_Engine_nextBuf( BLex3_Engine* m )
609|{
610| m->fp = m->buf_over;
611|}
612|
613|/**************************************************************************
614|* 24. <<< [BLex3_Engine_nextByPtr] ファイルポインタを進める(アドレス指定) >>>
615|*【引数】
616|* ・BLex3_Engine* m; 字句解析エンジン
617|* ・char* next_fp; ファイルポインタ(→補足)
618|*【補足】
619|*・本関数は、BLex3_Engine_getFilePtr 関数で取得したポインタ fp を進めた
620|* アドレス next_fp = fp + n に m のファイルポインタを合わせます。
621|*・next_fp は、BLex3_Engine_getFilePtr 関数から取得できる内部バッファの
622|* アドレスを指定します。内部バッファの外(前後)を指定しても、その位置に相当する
623|* ファイルアドレスに正しく設定します。
624|***************************************************************************/
625|void BLex3_Engine_nextByPtr( BLex3_Engine* m, char* next_fp )
626|{
627| m->fp = next_fp;
628| m->pos.sjis_type = BLex3_SJisUnknown;
629|}
630|
631|/**************************************************************************
632|* 25. <<< [BLex3_Engine_getPos] ファイルポインタのある位置のファイルアドレスを返す >>>
633|*【引数】
634|* ・BLex3_Engine* m; 字句解析エンジン
635|* ・BLex3_Pos* pos; (出力)ファイルアドレス
636|*【補足】
637|*・BLex3_Engine_getPos2 関数の fp 引数に、BLex3_Engine_getFilePtr 関数の返り値を
638|* そのまま指定したものと同じです。
639|***************************************************************************/
640|void BLex3_Engine_getPos( BLex3_Engine* m, BLex3_Pos* pos )
641|{
642| if ( m->fp - m->buf < 0 )
643| BLex3_Engine_getFilePtr( m, 0 );
644| pos->pos = m->pos.pos + (m->fp - m->buf);
645| if ( m->sjis_buf != NULL )
646| pos->sjis_type = *( m->sjis_buf + (m->fp - m->buf) );
647|}
648|
649|
650|/**************************************************************************
651|* 26. <<< [BLex3_Engine_getPos0] ファイルポインタのある位置のファイルアドレスを返す >>>
652|*【引数】
653|* ・BLex3_Engine* m; 字句解析エンジン
654|* ・int 返り値; ファイルアドレス
655|*【補足】
656|*・本関数の返り値では、BLex3_Engine_setPos 関数が使えませんが、
657|* BLex3_Pos::pos とファイルアドレスの大小比較ができます。
658|***************************************************************************/
659|int BLex3_Engine_getPos0( BLex3_Engine* m )
660|{
661| return m->pos.pos + (m->fp - m->buf);
662|}
663|
664|
665|/**************************************************************************
666|* 27. <<< [BLex3_Engine_getPos2] ファイルアドレスを返す >>>
667|*【引数】
668|* ・BLex3_Engine* m; 字句解析エンジン
669|* ・char* fp; ファイルポインタ(→補足)
670|* ・BLex3_Pos* pos; (出力)ファイルアドレス
671|*【補足】
672|*・fp は、BLex3_Engine_getFilePtr 関数から取得できる内部バッファの
673|* アドレスを指定します。
674|*・fp の位置に対応するファイルアドレス(ファイルの先頭を0としたオフセット)
675|* を pos に格納します。取得したファイルアドレスは、BLex3_Engine_setPos 関数に使います。
676|***************************************************************************/
677|void BLex3_Engine_getPos2( BLex3_Engine* m, char* fp, BLex3_Pos* pos )
678|{
679| ASSERT( fp >= m->buf );
680|
681| pos->pos = m->pos.pos + ( fp - m->buf );
682| if ( fp < m->buf_over ) {
683| pos->sjis_type = *( m->sjis_buf + (fp - m->buf) );
684| }
685|
686| /* 内部バッファより後のアドレスを返すとき、sjis_type を求める */
687| else {
688| char* p = m->sjis_buf + (m->buf_over - m->buf) - 1;
689| int n;
690| int c;
691|
692| if ( *p == BLex3_SJisUnknown ) return;
693|
694| /* 内部バッファの直後の文字について */
695| if ( *p == BLex3_SJisFirst ) {
696| if ( fp == m->buf_over ) {
697| pos->sjis_type = BLex3_SJisSecond;
698| return;
699| }
700| fseek( m->f, pos->pos + 1, SEEK_SET );
701| n = fp - m->buf_over - 1;
702| }
703| else {
704| fseek( m->f, pos->pos, SEEK_SET );
705| n = fp - m->buf_over;
706| }
707|
708| /* 内部バッファの直後より後の文字について */
709| for(;;) {
710| c = fgetc( m->f );
711| if ( _ismbblead( c ) ) {
712| if ( n == 0 )
713| { pos->sjis_type = BLex3_SJisFirst; return; }
714| else if ( n == 1 )
715| { pos->sjis_type = BLex3_SJisSecond; return; }
716| fgetc( m->f );
717| n--;
718| }
719| else {
720| if ( n == 0 )
721| { pos->sjis_type = BLex3_Ascii; return; }
722| }
723| n--;
724| }
725| }
726|}
727|
728|
729|/**************************************************************************
730|* 28. <<< [BLex3_Engine_getPos3] ファイルアドレスを返す >>>
731|*【引数】
732|* ・BLex3_Engine* m; 字句解析エンジン
733|* ・int n; 現在のファイルポインタの位置からの相対位置
734|* ・BLex3_Pos* pos; (出力)ファイルアドレス
735|*【補足】
736|*・相対位置が内部バッファの外でも構いません。
737|***************************************************************************/
738|void BLex3_Engine_getPos3( BLex3_Engine* m, int n, BLex3_Pos* pos )
739|{
740| ASSERT( n >= 0 && n < m->buf_over - m->buf );
741|
742| if ( m->fp + n > m->buf_over ) {
743| BLex3_Pos here;
744|
745| Errors_notSupport();
746| BLex3_Engine_getPos( m, &here );
747| BLex3_Engine_next( m, n );
748| BLex3_Engine_getPos( m, pos );
749| BLex3_Engine_setPos( m, &here ); /* ファイルポインタがずれる */
750| }
751| else {
752| if ( m->fp + n == m->buf_over )
753| BLex3_Engine_getFilePtr( m, n + 1 );
754|
755| pos->pos = m->pos.pos + ( m->fp - m->buf ) + n;
756| pos->sjis_type = *( m->sjis_buf + (m->fp - m->buf) + n );
757| }
758|}
759|
760|
761|/**************************************************************************
762|* 29. <<< [BLex3_Engine_getEndPos] ファイルの最後のファイルアドレスを返す >>>
763|*【引数】
764|* ・BLex3_Engine* m; 字句解析エンジン
765|* ・BLex3_Pos* pos; (出力)最後のファイルアドレス
766|***************************************************************************/
767|void BLex3_Engine_getEndPos( BLex3_Engine* m, BLex3_Pos* pos )
768|{
769| fseek( m->f, 0, SEEK_END );
770| pos->pos = ftell( m->f );
771| pos->sjis_type = BLex3_SJisUnknown;
772|}
773|
774|
775|/**************************************************************************
776|* 30. <<< [BLex3_Engine_setPos] ファイルポインタを指定のファイルアドレスに移動する >>>
777|*【引数】
778|* ・BLex3_Engine* m; 字句解析エンジン
779|* ・BLex3_Pos* pos; ファイルアドレス
780|*【補足】
781|*・pos は、BLex3_Engine_getPos 関数から取得したものを指定します。
782|*・本関数を使って移動した位置のファイルの内容は、BLex3_Engine_getFilePtr 関数
783|* を使って取得したファイルポインタを使って参照します。
784|***************************************************************************/
785|void BLex3_Engine_setPos( BLex3_Engine* m, BLex3_Pos* pos )
786|{
787| ASSERT( pos->pos != BLex3_nullPos.pos );
788|
789| m->fp = m->buf + ( pos->pos - m->pos.pos );
790| m->pos.sjis_type = pos->sjis_type;
791|}
792|
793|
794|/**************************************************************************
795|* 31. <<< [BLex3_Engine_setPos2] ファイルポインタを移動する(相対位置指定) >>>
796|*【引数】
797|* ・BLex3_Engine* m; 字句解析エンジン
798|* ・BLex3_Pos* pos; ファイルアドレス
799|* ・int n; pos からの相対位置(0以上)
800|***************************************************************************/
801|void BLex3_Engine_setPos2( BLex3_Engine* m, BLex3_Pos* pos, int n )
802|{
803| bool f = ( pos->pos < m->pos.pos );
804|
805| BLex3_Engine_setPos( m, pos );
806| if ( f && m->sjis_buf != NULL )
807| BLex3_Engine_getFilePtr( m, 0 );
808| BLex3_Engine_next( m, n );
809|}
810|
811|
812|/**************************************************************************
813|* 32. <<< [BLex3_Engine_copy] 入力ファイルの一部をそのままファイルに出力する >>>
814|*【引数】
815|* ・BLex3_Engine* m; 字句解析エンジン
816|* ・FILE* out; 出力ファイル
817|* ・BLex3_Pos* start; 出力を開始する入力ファイルのアドレス
818|* ・BLex3_Pos* over; 最後の出力をする入力ファイルのアドレスの次
819|***************************************************************************/
820|#if 0
821|void BLex3_Engine_copy( BLex3_Engine* m, FILE* out,
822| BLex3_Pos* start, BLex3_Pos* over )
823|{
824| char* p = m->buf + ( start->pos - m->pos.pos );
825| int overPos = m->pos.pos + ( m->buf_over - m->buf );
826| int c;
827| char* cp;
828|
829| ASSERT( start->pos <= over->pos );
830|
831| BLex3_Engine_setPos( m, start );
832| while ( overPos < over->pos ) {
833| fputs( p, out );
834| BLex3_Engine_nextBuf( m );
835| p = BLex3_Engine_getFilePtr( m, 0 );
836| if ( p == NULL ) return;
837| overPos = m->pos.pos + ( m->buf_over - m->buf );
838| }
839| cp = m->buf + ( over->pos - m->pos.pos );
840| c = *cp;
841| *cp = '\0';
842| fputs( p, out );
843| *cp = c;
844|}
845|#endif
846|
847|
848|/*---------------------------------------------------------------------*/
849|/* 33. <<<◆(BLex3_EngineU) 字句解析エンジン・ユーティリティ >>> */
850|/*---------------------------------------------------------------------*/
851|
852|void BLex3_EngineU_writeHTML_sub( char* data, char* data_over, int* iLine,
853| FILE* out );
854|void BLex3_EngineU_getStr_sub( char* fp, char* fp_over,
855| char** ps, int* ps_size );
856|
857|/**************************************************************************
858|* 34. <<< [BLex3_EngineU_readWord] 指定の区切り文字が現れるまで読み込む >>>
859|*【引数】
860|* ・BLex3_EngineU* m; 字句解析エンジン・ユーティリティ
861|* ・char* s; 読込んだデータを格納する領域の先頭アドレス
862|* ・int s_size; s の領域のサイズ
863|* ・char* terms; 区切り文字の並び
864|* ・bool bDQ; ダブルクォーテーションで囲むものを有効にするかどうか
865|*【補足】
866|*・現在のファイルポインタの位置(BLex3_Engine_getFilePtr で取得できるアドレス)
867|* から区切り文字(またはファイルの最後、または s_size)までを s に読み込みます。
868|*・s の最後は、'\0'文字が格納されます。
869|*・現在のファイルポインタの位置が " のとき、かつ bDQ が true のとき、
870|* terms に関係無く、"" で囲まれた部分を読み込みます。
871|*・本関数を実行したら、現在のファイルポインタの位置が、区切り文字のある
872|* 位置(または、ファイルの最後)に移動します。
873|***************************************************************************/
874|void BLex3_EngineU_readWord( BLex3_EngineU* m,
875| char* s, int s_size, const char* terms, bool bDQ )
876|{
877| char* fp;
878| char* p;
879| const char* dq = "\"";
880| ArrX_Buf s_buf;
881|
882| ArrX_Buf_init( &s_buf, s, s_size );
883| ArrX_Buf_addStr( &s_buf, "" );
884|
885| fp = BLex3_Engine_getFilePtr( &m->inherit_BLex3_Engine, 0 );
886| if ( bDQ && *fp == '\"' ) {
887| terms = dq;
888| BLex3_Engine_next( &m->inherit_BLex3_Engine, 1 );
889| fp = BLex3_Engine_getFilePtr( &m->inherit_BLex3_Engine, 0 );
890| }
891|
892| while ( fp != NULL ) {
893|
894| p = StrX_strchrs( fp, terms );
895| for (;;) {
896|
897| /* 次のバッファへ: to next buffer */
898| if ( p == NULL ) {
899| ArrX_Buf_addMem( &s_buf, fp,
900| BLex3_Engine_getOverPtr( &m->inherit_BLex3_Engine ) - fp );
901| BLex3_Engine_nextBuf( &m->inherit_BLex3_Engine );
902| fp = BLex3_Engine_getFilePtr( &m->inherit_BLex3_Engine, 0 );
903| break;
904| }
905|
906| /* "" で囲まれた文字列中に " が連続していたとき: case of "" in "" */
907| else if ( terms == dq && *p == '\"' && *(p + 1) == '\"' )
908| p = StrX_strchrs( p + 2, terms );
909|
910| /* 区切り文字が見つかったとき: case of find term char */
911| else
912| goto exit_while;
913| }
914| }
915| exit_while:
916|
917| ArrX_Buf_addMem( &s_buf, fp, p - fp );
918| ArrX_Buf_addChr( &s_buf, '\0' );
919| if ( fp != NULL ) {
920| if ( terms == dq ) p++;
921| BLex3_Engine_nextByPtr( &m->inherit_BLex3_Engine, p );
922| }
923|}
924|
925|
926|/**************************************************************************
927|* 35. <<< [BLex3_EngineU_skip] 指定の文字をスキップし続ける >>>
928|*【引数】
929|* ・BLex3_EngineU* m; 字句解析エンジン・ユーティリティ
930|* ・char* skipChars; スキップする文字を並べた文字列
931|*【補足】
932|*・現在のファイルポインタの位置(BLex3_Engine_getFilePtr で取得できるアドレス)
933|* から skipChars に含まれる(半角)文字をスキップして、現在のファイルポインタの
934|* 位置を進めます。
935|*【例】
936|* BLex3_EngineU_skip( &eng, " \t\r\n" ); // 空白とタブと改行をスキップ
937|***************************************************************************/
938|void BLex3_EngineU_skip( BLex3_EngineU* m, const char* skipChars )
939|{
940| BLex3_Engine* eng = &m->inherit_BLex3_Engine;
941| char* fp;
942| char* p;
943|
944| for (;;) {
945| fp = BLex3_Engine_getFilePtr( eng, 0 );
946| if ( fp == NULL ) return;
947| p = StrX_strchrs_not( fp, skipChars );
948| if ( p != NULL ) break;
949| BLex3_Engine_nextBuf( eng );
950| }
951| BLex3_Engine_nextByPtr( eng, p );
952|}
953|
954|
955|/**************************************************************************
956|* 36. <<< [BLex3_EngineU_skipTo] 指定の文字までスキップし続ける >>>
957|*【引数】
958|* ・BLex3_EngineU* m; 字句解析エンジン・ユーティリティ
959|* ・char* terms; スキップを止める文字を並べた文字列
960|* ・int plus; terms に含まれる文字のある位置からずらす量
961|*【補足】
962|*・現在のファイルポインタの位置(BLex3_Engine_getFilePtr で取得できるアドレス)
963|* から terms に含まれる(半角)文字までスキップして、現在のファイルポインタの
964|* 位置を進めます。
965|*・plus に +1 を指定すると、terms に含まれる文字の次の位置に、現在の
966|* ファイルポインタの位置を進めます。
967|*【例】
968|* BLex3_EngineU_skipTo( &eng, "\n", 1 ); // 次の行までスキップする
969|***************************************************************************/
970|void BLex3_EngineU_skipTo( BLex3_EngineU* m, const char* terms, int plus )
971|{
972| BLex3_Engine* eng = &m->inherit_BLex3_Engine;
973| char* fp;
974| char* fp2;
975| char* p;
976|
977| for (;;) {
978| fp = BLex3_Engine_getFilePtr( eng, 2 );
979| if ( fp == NULL ) return;
980| fp2 = BLex3_Engine_getSJisPtr( eng );
981| if ( *fp2 == BLex3_SJisSecond ) fp++;
982| p = StrX_strchrs2( fp, terms );
983| if ( p != NULL ) break;
984| BLex3_Engine_nextBuf( eng );
985| }
986| BLex3_Engine_nextByPtr( eng, p + plus );
987|}
988|
989|
990|/**************************************************************************
991|* 37. <<< [BLex3_EngineU_skipToStr] 指定の文字列までスキップし続ける >>>
992|*【引数】
993|* ・BLex3_EngineU* m; 字句解析エンジン・ユーティリティ
994|* ・char* term; スキップを止める文字を並べた文字列
995|* ・int plus; term に含まれる文字のある位置からずらす量
996|* ・bool bCase; 大文字小文字を区別するかどうか
997|*【補足】
998|*・現在のファイルポインタの位置(BLex3_Engine_getFilePtr で取得できるアドレス)
999|* から term に一致する位置までスキップして、現在のファイルポインタの位置を進めます。
1000|*・plus に +1 を指定すると、term に一致する先頭の位置の次の位置に、現在の
1001|* ファイルポインタの位置を進めます。
1002|*【例】
1003|* BLex3_EngineU_skipToStr( &eng, "end", 3, false ); // end の次までスキップする
1004|***************************************************************************/
1005|void BLex3_EngineU_skipToStr( BLex3_EngineU* m, const char* term, int plus,
1006| bool bCase )
1007|{
1008| BLex3_Engine* eng = &m->inherit_BLex3_Engine;
1009| const int term_len = strlen( term );
1010| char* fp;
1011| char* p;
1012| int hittingCount = 0;
1013|
1014| for (;;) {
1015| fp = BLex3_Engine_getFilePtr( eng, term_len );
1016| p = StrX_stristr3( fp, term, bCase, &hittingCount );
1017| if ( p != NULL ) break;
1018| BLex3_Engine_nextBuf( eng );
1019| }
1020| BLex3_Engine_nextByPtr( eng, p + plus );
1021|}
1022|
1023|
1024|/**************************************************************************
1025|* 38. <<< [BLex3_EngineU_skipTag] HTML のタグをスキップする >>>
1026|*【引数】
1027|* ・BLex3_EngineU* m; 字句解析エンジン・ユーティリティ
1028|***************************************************************************/
1029|void BLex3_EngineU_skipTag( BLex3_EngineU* m )
1030|{
1031| char* fp;
1032| char* fp_over;
1033|
1034| fp = BLex3_Engine_getFilePtr( &m->inherit_BLex3_Engine, 4 );
1035| fp_over = BLex3_Engine_getOverPtr( &m->inherit_BLex3_Engine );
1036|
1037| ASSERT( *fp == '<' );
1038|
1039| if ( strncmp( fp + 1, "!--", 3 ) == 0 ) {
1040| BLex3_EngineU_skipToStr( m, "-->", +3, true );
1041| }
1042| else {
1043| BLex3_EngineU_skipTo( m, ">", +1 );
1044| }
1045|}
1046|
1047|/**************************************************************************
1048|* 39. <<< [BLex3_EngineU_write] 指定の範囲をファイルに出力する >>>
1049|*【引数】
1050|* ・BLex3_EngineU* m; 字句解析エンジン・ユーティリティ
1051|* ・BLex3_Pos* firstPos; 出力開始位置
1052|* ・BLex3_Pos* overPos; 出力終了の次の位置
1053|* ・FILE* out; 出力ファイル
1054|*【補足】
1055|*・本関数を呼び出したら、BLex3_Engine_setPos 関数と BLex3_Engine_getFilePtr
1056|* 関数を呼び出して、ファイルポインタの位置を再取得してください。
1057|***************************************************************************/
1058|void BLex3_EngineU_write( BLex3_EngineU* m, BLex3_Pos* firstPos,
1059| BLex3_Pos* overPos, FILE* out )
1060|{
1061| BLex3_Engine* eng = &m->inherit_BLex3_Engine;
1062| char* fp;
1063| char* fp_over;
1064| BLex3_Pos pos;
1065|
1066| ASSERT( firstPos->pos <= overPos->pos );
1067|
1068| BLex3_Engine_setPos( eng, firstPos );
1069| for (;;) {
1070| fp = BLex3_Engine_getFilePtr( eng, 0 );
1071| fp_over = BLex3_Engine_getOverPtr( eng );
1072| BLex3_Engine_getPos2( eng, fp_over, &pos );
1073| if ( overPos->pos > pos.pos ) {
1074| fwrite( fp, fp_over - fp, 1, out );
1075| BLex3_Engine_nextBuf( eng );
1076| }
1077| else {
1078| fp_over = BLex3_Engine_getFilePtrByPos( eng, overPos->pos );
1079| fwrite( fp, fp_over - fp, 1, out );
1080| return;
1081| }
1082| }
1083|}
1084|
1085|
1086|/**************************************************************************
1087|* 40. <<< [BLex3_EngineU_writeHTML] 指定の範囲のテキストを HTML ファイルに出力する >>>
1088|*【引数】
1089|* ・BLex3_EngineU* m; 字句解析エンジン・ユーティリティ
1090|* ・BLex3_Pos* firstPos; 出力開始位置
1091|* ・BLex3_Pos* overPos; 出力終了の次の位置
1092|* ・int iLine; 出力開始位置の行番号(-1で行番号を出力しない)
1093|* ・FILE* out; 出力ファイル
1094|*【補足】
1095|*・<, >, & を <, >, & に変換します。
1096|*・行番号を出力します。
1097|*・特定のタグをそのまま出力するときは、HtmlPars を使って特定のタグを判定し、
1098|* BLex3_EngineU_write 関数でファイルに出力します。
1099|***************************************************************************/
1100|void BLex3_EngineU_writeHTML( BLex3_EngineU* m, BLex3_Pos* firstPos,
1101| BLex3_Pos* overPos, int iLine, FILE* out )
1102|{
1103| BLex3_Engine* eng = &m->inherit_BLex3_Engine;
1104| char* fp;
1105| char* fp_over;
1106| BLex3_Pos pos;
1107|
1108| ASSERT( firstPos->pos <= overPos->pos );
1109| if ( firstPos->pos == overPos->pos ) return;
1110|
1111| BLex3_Engine_setPos( eng, firstPos );
1112| for (;;) {
1113| fp = BLex3_Engine_getFilePtr( eng, 0 );
1114| fp_over = BLex3_Engine_getOverPtr( eng );
1115| BLex3_Engine_getPos2( eng, fp_over, &pos );
1116| if ( overPos->pos > pos.pos ) {
1117| BLex3_EngineU_writeHTML_sub( fp, fp_over, &iLine, out );
1118| BLex3_Engine_nextBuf( eng );
1119| }
1120| else {
1121| fp_over = BLex3_Engine_getFilePtrByPos( eng, overPos->pos );
1122| BLex3_EngineU_writeHTML_sub( fp, fp_over, &iLine, out );
1123| return;
1124| }
1125| }
1126|}
1127|
1128|
1129|/**************************************************************************
1130|* 41. <<< [BLex3_EngineU_writeHTML_sub] テキストデータを HTML ファイルに出力する >>>
1131|*【引数】
1132|* ・char* data; 出力するテキストファイルの内容の先頭アドレス
1133|* ・char* data_over; 同、末尾の次のアドレス
1134|* ・int* piLine; (入力)data の行番号、(出力)data_over の行番号
1135|* ・FILE* out; 出力ファイル
1136|*【補足】
1137|*・BLex3_EngineU_writeHTML のサブルーチンです。
1138|***************************************************************************/
1139|void BLex3_EngineU_writeHTML_sub( char* data, char* data_over, int* piLine,
1140| FILE* out )
1141|{
1142| char* p;
1143| char* tp = data; /* そのまま出力する先頭 */
1144| int iLine = *piLine;
1145|
1146| for ( p = data; p < data_over; p++ ) {
1147| switch ( *p ) {
1148| case '<':
1149| fwrite( tp, p - tp, 1, out ); tp = p + 1;
1150| fputs( "<", out );
1151| break;
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 '\n':
1161| if ( iLine != -1 ) {
1162| fwrite( tp, p - tp, 1, out ); tp = p + 1;
1163| iLine ++;
1164| fprintf( out, "\n%4d|", iLine );
1165| }
1166| break;
1167| }
1168| }
1169| fwrite( tp, p - tp, 1, out );
1170| *piLine = iLine;
1171|}
1172|
1173|/**************************************************************************
1174|* 42. <<< [BLex3_EngineU_writeNoTag] HTML タグを除いた HTML をテキストファイルに出力する >>>
1175|*【引数】
1176|* ・BLex3_EngineU* m; 字句解析エンジン・ユーティリティ
1177|* ・BLex3_Pos* firstPos; 出力開始位置
1178|* ・BLex3_Pos* overPos; 出力終了の次の位置
1179|* ・FILE* out; 出力ファイル
1180|*【補足】
1181|*・firstPos から overPos までの HTML テキストから <, > で囲まれた HTML タグを
1182|* カットして、テキストファイルに出力します。
1183|*・firstPos から overPos までの先頭または末尾の空白、タブ、改行もカットします。
1184|***************************************************************************/
1185|void BLex3_EngineU_writeNoTag( BLex3_EngineU* m, BLex3_Pos* firstPos,
1186| BLex3_Pos* overPos, FILE* out )
1187|{
1188| BLex3_Engine* eng = &m->inherit_BLex3_Engine;
1189| char* fp;
1190| char* fp_over;
1191| char* fp_writeOver;
1192| bool bSpc; /* 空白、タブ、改行、HTML タグが続いているかどうか */
1193| BLex3_Pos topPos;
1194| BLex3_Pos pos;
1195| int c;
1196|
1197| ASSERT( firstPos->pos <= overPos->pos );
1198|
1199| /* 最初の空白や HTML タグをスキップする */
1200| BLex3_Engine_setPos( eng, firstPos );
1201| fp = BLex3_Engine_getFilePtr( eng, 0 );
1202| fp_over = BLex3_Engine_getOverPtr( eng );
1203|
1204| for (;;) {
1205| c = *fp;
1206| if ( c == ' ' || c == '\t' || c == '\r' || c == '\n' ) {
1207| fp++;
1208| if ( fp == fp_over ) {
1209| BLex3_Engine_nextBuf( eng );
1210| fp = BLex3_Engine_getFilePtr( eng, 0 );
1211| fp_over = BLex3_Engine_getOverPtr( eng );
1212| }
1213| }
1214| else if ( c == '<' ) {
1215| BLex3_Engine_nextByPtr( eng, fp );
1216| BLex3_EngineU_skipTag( m );
1217| fp = BLex3_Engine_getFilePtr( eng, 0 );
1218| fp_over = BLex3_Engine_getOverPtr( eng );
1219| }
1220| else
1221| break;
1222| }
1223| fp_writeOver = BLex3_Engine_getFilePtrByPos2( eng, overPos->pos );
1224| if ( fp_writeOver < fp_over ) fp_over = fp_writeOver;
1225|
1226| /* 末尾の空白や HTML タグの前までファイルに出力する */
1227| bSpc = false;
1228| BLex3_Engine_getPos2( eng, fp, &topPos );
1229|
1230| for (;;) {
1231| c = *fp;
1232| if ( c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '<' ) {
1233|
1234| /* 空白などが始まったら、それまでを出力する */
1235| if ( ! bSpc ) {
1236| BLex3_Engine_getPos2( eng, fp, &pos );
1237| BLex3_EngineU_write( m, &topPos, &pos, out );
1238|
1239| BLex3_Engine_setPos( eng, &pos );
1240| fp = BLex3_Engine_getFilePtr( eng, 0 );
1241| fp_over = BLex3_Engine_getOverPtr( eng );
1242| fp_writeOver = BLex3_Engine_getFilePtrByPos2( eng, overPos->pos );
1243| if ( fp_writeOver < fp_over ) fp_over = fp_writeOver;
1244|
1245| BLex3_Pos_copy( &topPos, &pos );
1246| bSpc = true;
1247| }
1248|
1249| /* タグをスキップする */
1250| if ( c == '<' ) {
1251| BLex3_Engine_nextByPtr( eng, fp );
1252| BLex3_EngineU_skipTag( m );
1253| BLex3_Engine_getPos( eng, &topPos );
1254| fp = BLex3_Engine_getFilePtr( eng, 0 );
1255| fp_over = BLex3_Engine_getOverPtr( eng );
1256| fp_writeOver = BLex3_Engine_getFilePtrByPos2( eng, overPos->pos );
1257| if ( fp_writeOver < fp_over ) fp_over = fp_writeOver;
1258| }
1259| else
1260| fp++;
1261| }
1262| else {
1263| bSpc = false;
1264| fp++;
1265| }
1266|
1267| /* fp が内部バッファを超えたら更新する */
1268| if ( fp >= fp_over ) {
1269| if ( fp >= fp_writeOver ) {
1270| break;
1271| }
1272| BLex3_Engine_nextBuf( eng );
1273| fp = BLex3_Engine_getFilePtr( eng, 0 );
1274| fp_over = BLex3_Engine_getOverPtr( eng );
1275| fp_writeOver = BLex3_Engine_getFilePtrByPos2( eng, overPos->pos );
1276| if ( fp_writeOver < fp_over ) fp_over = fp_writeOver;
1277| }
1278| }
1279|
1280| /* 最後が空白でなかったら、最後まで出力する */
1281| if ( ! bSpc ) {
1282| BLex3_EngineU_write( m, &topPos, overPos, out );
1283| }
1284|}
1285|
1286|
1287|/**************************************************************************
1288|* 43. <<< [BLex3_EngineU_getStr] 指定の範囲を文字列として取得する >>>
1289|*【引数】
1290|* ・BLex3_EngineU* m; 字句解析エンジン・ユーティリティ
1291|* ・BLex3_Pos* firstPos; 出力開始位置
1292|* ・BLex3_Pos* overPos; 出力終了の次の位置
1293|* ・char* s; 文字列を格納する領域の先頭アドレス
1294|* ・int s_size; s のサイズ
1295|***************************************************************************/
1296|void BLex3_EngineU_getStr( BLex3_EngineU* m, BLex3_Pos* firstPos,
1297| BLex3_Pos* overPos, char* s, int s_size )
1298|{
1299| BLex3_Engine* eng = &m->inherit_BLex3_Engine;
1300| char* fp;
1301| char* fp_over;
1302| BLex3_Pos pos;
1303|
1304| ASSERT( firstPos->pos <= overPos->pos );
1305|
1306| BLex3_Engine_setPos( eng, firstPos );
1307| for (;;) {
1308| fp = BLex3_Engine_getFilePtr( eng, 0 );
1309| fp_over = BLex3_Engine_getOverPtr( eng );
1310| BLex3_Engine_getPos2( eng, fp_over, &pos );
1311| if ( overPos->pos > pos.pos ) {
1312| BLex3_EngineU_getStr_sub( fp, fp_over, &s, &s_size );
1313| if ( s_size <= 0 ) return;
1314| BLex3_Engine_nextBuf( eng );
1315| }
1316| else {
1317| fp_over = BLex3_Engine_getFilePtrByPos( eng, overPos->pos );
1318| BLex3_EngineU_getStr_sub( fp, fp_over, &s, &s_size );
1319| return;
1320| }
1321| }
1322|}
1323|
1324|
1325|/**************************************************************************
1326|* 44. <<< [BLex3_EngineU_getStr_sub] テキストデータを文字列として取得する >>>
1327|*【引数】
1328|* ・char* fp; 出力するテキストファイルの内容の先頭アドレス
1329|* ・char* fp_over; 同、末尾の次のアドレス
1330|* ・char* ps; (入力)取得領域のアドレス、(出力)次の取得アドレス
1331|* ・int* ps_size; (入力)取得領域のサイズ、(出力)残りのサイズ
1332|*【補足】
1333|*・BLex3_EngineU_getStr のサブルーチンです。
1334|***************************************************************************/
1335|void BLex3_EngineU_getStr_sub( char* fp, char* fp_over,
1336| char** ps, int* ps_size )
1337|{
1338| char* s = *ps;
1339| int s_size_1 = *ps_size - 1;
1340| int f_size = fp_over - fp;
1341|
1342| if ( f_size < s_size_1 ) {
1343| memcpy( s, fp, f_size );
1344| s[f_size] = '\0';
1345| *ps = s + f_size;
1346| (*ps_size) -= f_size;
1347| }
1348| else {
1349| memcpy( s, fp, s_size_1 );
1350| s[s_size_1] = '\0';
1351| *ps = s + s_size_1;
1352| (*ps_size) -= s_size_1;
1353| }
1354|}
1355|
1356|/*---------------------------------------------------------------------*/
1357|/* 45. <<<◆(BLex3_Parser) パーサ >>> */
1358|/*---------------------------------------------------------------------*/
1359|
1360|
1361|/***********************************************************************
1362|* 46. <<< BLex3_Parser インターフェイス・関数定義 >>>
1363|************************************************************************/
1364|#ifndef NDEBUG
1365|INF_FUNC_0( BLex3_Parser, finish, void, BLex3_Parser_finish, BLex3_Parser, t );
1366|INF_FUNC_1( BLex3_Parser, linkEngine, void, BLex3_Parser_setEngine, BLex3_Parser, BLex3_Engine*, t,a );
1367|INF_FUNC_0( BLex3_Parser, parse, void, BLex3_Parser_parse, BLex3_Parser, t );
1368|INF_FUNC_R0( BLex3_Parser, getTokenType, int, BLex3_Parser_getTokenType, BLex3_Parser, t );
1369|INF_FUNC_1( BLex3_Parser, getNextParsePos, void, BLex3_Parser_getNextParsePos, BLex3_Parser, BLex3_Pos*, t,a );
1370|INF_FUNC_0( BLex3_Parser, printLastMsg, void, BLex3_Parser_printLastMsg, BLex3_Parser, t );
1371|#endif
1372|
1373|
1374|