TNB Library
TnbGrammarAnalyzer.h
[詳解]
1#pragma once
13#include "TnbStr.h"
14
15
16
17//T-TestCaseコードカバレッジDisable
18#pragma comment(user,"T-Coverage Disable")
19
20
21
22//TNB Library
23namespace TNB
24{
25
26
27
43template<typename TYP = TCHAR, typename ITE = const TYP*>
45{
46public:
47
59 struct IFormat
60 {
62 virtual ~IFormat(void){}
63
72 virtual bool IsBlankChar(TYP c) const
73 {
74 return (c == ' ' || c == '\t');
75 }
76
85 virtual bool IsTokenPeriodChar(TYP c) const
86 {
87 switch ( c )
88 {
89 case 0: case '=': case ' ': case '\t':
90 case ',': case 0x0D: case 0x0A: case '/':
91 case '*': case '(': case ')': case ']':
92 case '[': case ':': case '{': case '}':
93 case '!': case '+': case '-': case '<':
94 case '>': case ';': case '\"': case '.':
95 case 0x1A:
96 return true;
97 }
98 return false;
99 }
100
109 virtual bool IsEndChar(TYP c) const
110 {
111 return c == 0;
112 }
113
122 virtual TYP CheckBlockStartChar(TYP c) const
123 {
124 TYP r = 0;
125 switch ( c )
126 {
127 case '(': r = ')'; break;
128 case '[': r = ']'; break;
129 case '{': r = '}'; break;
130 }
131 return r;
132 }
133
142 virtual bool IsBlockCloseChar(TYP c) const
143 {
144 switch ( c )
145 {
146 case ')': break;
147 case ']': break;
148 case '}': break;
149 default:
150 return false;
151 }
152 return true;
153 }
154
164 virtual bool IsStringMarkChar(TYP c) const
165 {
166 return (c == '\"' || c == '\"');
167 }
168
179 virtual int CheckStringSpecialWord(CStrT<TYP>& _str, ITE ite) const
180 {
181 if ( *ite != '\\' )
182 {
183 return 0;
184 }
185 _str.Empty();
186 ite++;
187 switch ( *ite )
188 {
189 case '\\':
190 case '\042':
191 _str = "\\";
192 _str += *ite;
193 break;
194 case 'n':
195 _str = "\n";
196 break;
197 case 'r':
198 _str = "\r";
199 break;
200 default:
201 return 0;
202 }
203 return 2;
204 }
205
216 virtual int CheckComment(CStrT<TYP>& _str, ITE ite) const
217 {
218 if ( *ite != '/' )
219 {
220 return 0;
221 }
222 ite++;
223 if ( *ite == '/' )
224 {
225 return -1;
226 }
227 if ( *ite == '*' )
228 {
229 _str = "*/";
230 return 2;
231 }
232 return 0;
233 }
234 };
235
238 {
248 };
249
261 class CParts
262 {
263 public:
264
266 CParts(void) : m_kind(FINAL), m_str(), m_line(0), m_raw(0)
267 {
268 }
269
277 CParts(EPartsKind kind, const CStrT<TYP>& s, INT_PTR l, INT_PTR r)
278 : m_kind(kind), m_str(s), m_line(l), m_raw(r)
279 {
280 }
281
289 CParts(EPartsKind kind, TYP c, INT_PTR l, INT_PTR r)
290 : m_kind(kind), m_str(), m_line(l), m_raw(r)
291 {
292 TYP at[2] = {c, 0};
293 m_str = at;
294 }
295
300 CParts(const CParts& other)
301 : m_kind(other.m_kind), m_str(other.m_str), m_line(other.m_line), m_raw(other.m_raw)
302 {
303 }
304
310 CParts& operator=(const CParts& other)
311 {
312 m_kind = other.m_kind;
313 m_str = other.m_str;
314 m_line = other.m_line;
315 m_raw = other.m_raw;
316 return *this;
317 }
318
323 EPartsKind GetKind(void) const
324 {
325 return m_kind;
326 }
327
334 bool IsEqualString(LPCSTR lpsz) const
335 {
336 return m_str.IsEqual(lpsz);
337 }
338
343 const TYP* GetString(void) const
344 {
345 return m_str;
346 }
347
353 TYP GetAt(INDEX index = 0) const
354 {
355 return (m_str.GetLength() > index) ? m_str[index] : static_cast<TYP>(0);
356 }
357
362 INT_PTR GetLine(void) const
363 {
364 return m_line;
365 }
366
371 INT_PTR GetRaw(void) const
372 {
373 return m_raw;
374 }
375
381 CStr ToString(void) const
382 {
383 CStr str;
384 switch ( m_kind )
385 {
386 case TOKEN: str = _T("トークン"); break;
387 case CHARACTOR: str = _T("文字"); break;
388 case STRING: str = _T("文字列"); break;
389 case PERIOD_CHAR: str = _T("トークン区切り文字"); break;
390 case OPEN_CHAR: str = _T("ブロック開始文字"); break;
391 case CLOSE_CHAR: str = _T("ブロック終端文字"); break;
392 case FINAL: str = _T("終わり"); break;
393 default: str = _T("エラー"); break;
394 }
395 return CStr::Fmt(_T("%s : [%s] (%d,%d)"), str, CStr(m_str), m_line, m_raw);
396 }
397
398 private:
399 EPartsKind m_kind;
400 CStrT<TYP> m_str;
401 INT_PTR m_line;
402 INT_PTR m_raw;
403 };
404
411 CGrammarAnalyzerT(ITE is = ITE(), ITE ie = ITE(), INT_PTR line = 1)
412 : m_param(is, ie, line), m_pFormat(&m_defaultFormat)
413 {
414 }
415
421 : m_param(other.m_param), m_pFormat(other.m_pFormat), m_strName(other.m_strName)
422 {
423 if ( other.m_pFormat == &other.m_defaultFormat )
424 {
425 m_pFormat = &m_defaultFormat;
426 }
427 }
428
435 {
436 m_param = other.m_param;
437 m_pFormat = other.m_pFormat;
438 m_strName = other.m_strName;
439 if ( other.m_pFormat == &other.m_defaultFormat )
440 {
441 m_pFormat = &m_defaultFormat;
442 }
443 return *this;
444 }
445
450 void SetFormat(const IFormat* P)
451 {
452 m_pFormat = (P == NULL) ? &m_defaultFormat : P;
453 }
454
460 void SetName(LPCTSTR name)
461 {
462 m_strName = name;
463 }
464
470 CStr GetName(void) const
471 {
472 return m_strName;
473 }
474
479 UINT_PTR GetLine(void) const
480 {
481 return m_param.line;
482 }
483
488 UINT_PTR GetRaw(void) const
489 {
490 return m_param.raw;
491 }
492
497 UINT_PTR GetPos(void) const
498 {
499 return m_param.pos;
500 }
501
507 ITE GetPointer(void)
508 {
509 m_SkipBlankChar();
510 return ite();
511 }
512
517 INT_PTR GetDepth(void) const
518 {
519 return m_param.strDepth.GetLength();
520 }
521
527 TYP GetBlockChar(void) const
528 {
529 int l = m_param.strDepth.GetLength();
530 return (l > 0) ? m_param.strDepth.GetAt(l - 1) : 0;
531 }
532
540 CParts GetNextParts(bool boIsToken = true)
541 {
542 CParts p;
543 m_SkipBlankChar();
544 if ( ! m_IsEnd() )
545 {
546 TYP c = *ite();
547 UINT_PTR line = GetLine();
548 UINT_PTR raw = GetRaw();
549 if ( m_pFormat->CheckBlockStartChar(c) != 0 )
550 {
551 // ブロック開始文字
552 p = CParts(OPEN_CHAR, c, line, raw);
553 inc();
554 m_param.strDepth += c;
555 }
556 else if ( m_pFormat->IsBlockCloseChar(c) )
557 {
558 //ブロック終端文字
559 if ( m_param.strDepth.IsEmpty() )
560 {
561 p = CParts(ERROR_DEPTH, c, line, raw);
562 }
563 else
564 {
565 p = CParts(CLOSE_CHAR, c, line, raw);
566 inc();
567 m_param.strDepth.DeleteLast();
568 }
569 }
570 else if ( m_pFormat->IsStringMarkChar(c) )
571 {
572 // 文字列
573 CStrT<TYP> str;
574 if ( m_GetString(str) < 0 )
575 {
576 //error
577 p = CParts(ERROR_STRING, str, line, raw);
578 }
579 else
580 {
581 p = CParts(STRING, str, line, raw);
582 }
583 }
584 else if ( m_pFormat->IsTokenPeriodChar(c) )
585 {
586 // トークン区切り文字
587 p = CParts(PERIOD_CHAR, c, line, raw);
588 inc();
589 }
590 else if ( boIsToken )
591 {
592 // トークン
593 CStrT<TYP> str;
594 m_GetToken(str);
595 p = CParts(TOKEN, str, line, raw);
596 }
597 else
598 {
599 CStrT<TYP> str;
600 str += c;
601 if ( STRLIB::GetCharSize(c) == 2 )
602 {
603 inc();
604 str += *ite();
605 }
606 inc();
607 p = CParts(CHARACTOR, str, line, raw);
608 }
609 }
610 return p;
611 }
612
618 bool SkipoutBlock(void)
619 {
620 if ( m_param.strDepth.IsEmpty() )
621 {
622 return false;
623 }
624 INT_PTR l = m_param.strDepth.GetLength();
625 TYP lc = m_pFormat->CheckBlockStartChar(m_param.strDepth.GetAt(l - 1));
626 if ( m_SkipToNextChar(lc) < 0 )
627 {
628 return false;
629 }
630 inc(); //終端の次へ
631 m_param.strDepth.DeleteLast();
632 return true;
633 }
634
641 CParts PeekNextParts(bool boIsToken = true)
642 {
643 TParam pm = m_param;
644 CParts r = GetNextParts(boIsToken);
645 m_param = pm;
646 return r;
647 }
648
656 INT_PTR StepPointer(INT_PTR step)
657 {
658 INT_PTR top = m_param.pos; // 現在のポジション
659 while ( (m_param.pos - top) < step )
660 {
661 GetNextParts();
662 }
663 return m_param.pos - top;
664 }
665
666private:
667
669 struct TParam
670 {
671 ITE iteNow;
672 ITE iteEnd;
673 INT_PTR pos;
674 INT_PTR line;
675 INT_PTR raw;
676 CStrT<TYP> strDepth;
677 // コンストラクタ
678 TParam(ITE is = ITE(), ITE ie = ITE(), INT_PTR l = 1) : iteNow(is), iteEnd(ie), pos(0), line(l), raw(0), strDepth()
679 {
680 }
681 // コピーコンストラクタ
682 TParam(const TParam& other)
683 : iteNow(other.iteNow), iteEnd(other.iteEnd), pos(other.pos)
684 , line(other.line), raw(other.raw), strDepth(other.strDepth)
685 {
686 }
687 // コピーオペレータ
688 TParam& operator=(const TParam& other)
689 {
690 iteNow = other.iteNow;
691 iteEnd = other.iteEnd;
692 pos = other.pos;
693 line = other.line;
694 raw = other.raw;
695 strDepth = other.strDepth;
696 return *this;
697 }
698 };
699
700 TParam m_param;
701 IFormat m_defaultFormat;
702 const IFormat* m_pFormat;
703 CStr m_strName;
704
706 ITE ite(void){ return m_param.iteNow; }
707 void inc(void) { m_param.iteNow++; m_param.pos++; m_param.raw++;}
708 void inc(INT_PTR i) { m_param.iteNow += i; m_param.pos += i; m_param.raw += i; }
709
711 class CStepCnt
712 {
713 UINT_PTR m_bak;
714 public:
715 CStepCnt(const TParam& t) : m_bak(t.pos) {}
716 UINT_PTR rst(const TParam& t){ return t.pos - m_bak; }
717 };
718
725 bool m_IsEnd(void)
726 {
727 if ( ite() != m_param.iteEnd && ! m_pFormat->IsEndChar(*ite()) )
728 {
729 return false;
730 }
731 return true;
732 }
733
739 INT_PTR m_SkipCr(void)
740 {
741 CStepCnt cnt(m_param);
742 ASSERTLIB( ! m_IsEnd() );
743 TYP c = *ite();
744 if ( c == 0x0D )
745 {
746 m_param.line++;
747 inc();
748 if ( *ite() == 0x0A )
749 {
750 inc();
751 }
752 m_param.raw = 0;
753 }
754 else if ( c == 0x0A )
755 {
756 m_param.line++;
757 inc();
758 m_param.raw = 0;
759 }
760 return cnt.rst(m_param);
761 }
762
770 bool m_IsEqual(const CStrT<TYP>& str)
771 {
772 ITE p = ite();
773 loop ( i, str.GetLength() )
774 {
775 if ( str[i] != *p )
776 {
777 return false;
778 }
779 p++;
780 }
781 return true;
782 }
783
790 void m_SkipBlankCharSub(INT_PTR r, const CStrT<TYP>& str)
791 {
792 ASSERTLIB( r != 0 );
793 if ( r > 0 )
794 {
795 inc(r);
796 }
797 while ( true )
798 {
799 if ( r > 0 && m_IsEqual(str) )
800 {
801 // str と同じ
802 inc(str.GetLength());
803 break;
804 }
805 if ( m_SkipCr() > 0 )
806 {
807 if ( r < 0 )
808 {
809 break;
810 }
811 }
812 else if ( m_IsEnd() )
813 {
814 break;
815 }
816 else
817 {
818 TYP c = *ite();
819 inc(STRLIB::GetCharSize(c));
820 }
821 }
822 }
823
829 INT_PTR m_SkipBlankChar(void)
830 {
831 CStepCnt cnt(m_param);
832 CStrT<TYP> str;
833 while ( true )
834 {
835 if ( m_IsEnd() )
836 {
837 break;
838 }
839 INT_PTR r = m_pFormat->CheckComment(str, ite());
840 if ( r != 0 )
841 {
842 m_SkipBlankCharSub(r, str);
843 }
844 else if ( m_SkipCr() > 0 )
845 {
846 ;
847 }
848 else if ( m_pFormat->IsBlankChar(*ite()) )
849 {
850 inc();
851 }
852 else
853 {
854 break;
855 }
856 }
857 return cnt.rst(m_param);
858 }
859
866 INT_PTR m_GetToken(CStrT<TYP>& _token)
867 {
868 CStepCnt cnt(m_param);
869 ASSERTLIB( ! m_IsEnd() );
870 _token.Empty();
871 while ( true )
872 {
873 TYP c = *ite();
874 if ( STRLIB::GetCharSize(c) == 2 )
875 {
876 _token += c;
877 inc();
878 _token += *ite();
879 }
880 else
881 {
882 if ( m_pFormat->IsTokenPeriodChar(c) )
883 {
884 if ( cnt.rst(m_param) == 0 )
885 {
886 _token += c;
887 inc();
888 }
889 break;
890 }
891 _token += c;
892 }
893 inc();
894 }
895// TRACE1("GrammarAnalyzer FoundToken = [%s]\n", CStr(_token));
896 ASSERT( cnt.rst(m_param) != 0 );
897 return cnt.rst(m_param);
898 }
899
905 INT_PTR m_SkipToken(void)
906 {
907 CStrT<TYP> s;
908 return m_GetToken(s);
909 }
910
917 INT_PTR m_SkipBlock(void)
918 {
919 CStepCnt cnt(m_param);
920 if ( m_pFormat->IsStringMarkChar(*ite()) )
921 {
922 m_SkipString();
923 }
924 else
925 {
926 TYP c = m_pFormat->CheckBlockStartChar(*ite());
927 if ( c != 0 )
928 {
929 inc();
930 m_SkipToNextChar(c);
931 if ( *ite() == c )
932 {
933 inc();
934 }
935 }
936 }
937 return cnt.rst(m_param);
938 }
939
946 INT_PTR m_SkipToNextChar(TYP cCloseChar)
947 {
948 CStepCnt cnt(m_param);
949 TParam pp = m_param;
950 while ( true )
951 {
952 m_SkipBlankChar();
953 if ( m_IsEnd() )
954 {
955 TRACE0("`('が綴じてません\n");
956 m_param = pp;
957 return -1;
958 }
959 TYP c = *ite();
960 if ( STRLIB::GetCharSize(c) == 2 )
961 {
962 inc(2);
963 }
964 else if ( c == cCloseChar )
965 {
966 break;
967 }
968 else if ( m_SkipBlock() > 0 )
969 {
970 ;
971 }
972 else
973 {
974 m_SkipToken();
975 }
976 }
977 return cnt.rst(m_param);
978 }
979
988 INT_PTR m_GetString(CStrT<TYP>& _str)
989 {
990 CStepCnt cnt(m_param);
991 ASSERTLIB( ! m_IsEnd() );
992 bool r = true;
993 _str.Empty();
994 TYP c = *ite();
995 if ( ! m_pFormat->IsStringMarkChar(c) )
996 {
997 return 0;
998 }
999 inc();
1000 TYP endChar = c;
1001 while ( true )
1002 {
1003 if ( m_IsEnd() )
1004 {
1005 break;
1006 }
1007 c = *ite();
1008 inc();
1009 if ( c == endChar )
1010 {
1011 break;
1012 }
1013 _str += c;
1014 if ( STRLIB::GetCharSize(c) == 2 )
1015 {
1016 _str += *ite();
1017 inc();
1018 }
1019 CStrT<TYP> s;
1020 INT_PTR l = m_pFormat->CheckStringSpecialWord(s, ite());
1021 if ( l < 0 )
1022 {
1023 r = false;
1024 inc();
1025 }
1026 else if ( l > 0 )
1027 {
1028 _str += s;
1029 inc(l);
1030 }
1031 }
1032 return r ? cnt.rst(m_param) : -1;
1033 }
1034
1042 INT_PTR m_SkipString(void)
1043 {
1044 CStrT<TYP> s;
1045 return m_GetString(s);
1046 }
1047
1048 friend class CGrammarAnalyzerTest;
1049};
1050
1051
1052
1062
1063
1064
1065}; // TNB
1066
1067
1068
1069//T-TestCaseコードカバレッジEnable
1070#pragma comment(user,"T-Coverage Enable")
1071
#define loop(VAR, CNT)
loop構文.
Definition: TnbDef.h:343
文字列管理関係のヘッダ
文法解析用パーツ管理クラス
CParts & operator=(const CParts &other)
コピーコンストラクタ
CParts(const CParts &other)
コピーコンストラクタ
CParts(EPartsKind kind, const CStrT< TYP > &s, INT_PTR l, INT_PTR r)
コンストラクタ
bool IsEqualString(LPCSTR lpsz) const
[比較] 内容比較
CParts(EPartsKind kind, TYP c, INT_PTR l, INT_PTR r)
コンストラクタ
TYP GetAt(INDEX index=0) const
[取得] 内容.
EPartsKind GetKind(void) const
[取得] 種類
INT_PTR GetLine(void) const
[取得] 行番号取得
INT_PTR GetRaw(void) const
[取得] 列番号取得
CParts(void)
コンストラクタ
CStr ToString(void) const
[取得] 文字列化.
const TYP * GetString(void) const
[取得] 内容
文法解析テンプレート
CGrammarAnalyzerT & operator=(const CGrammarAnalyzerT &other)
コピーオペレータ
UINT_PTR GetLine(void) const
[取得] 行番号取得
EPartsKind
パーツ種類コード
@ ERROR_DEPTH
深さエラー
@ OPEN_CHAR
ブロック開始文字
@ CLOSE_CHAR
ブロック終端文字
@ ERROR_STRING
文字列エラー
@ PERIOD_CHAR
トークン区切り文字
CGrammarAnalyzerT(ITE is=ITE(), ITE ie=ITE(), INT_PTR line=1)
コンストラクタ
INT_PTR GetDepth(void) const
[取得] 深さ取得
ITE GetPointer(void)
[取得] 現在のイテレータ
INT_PTR StepPointer(INT_PTR step)
[処理] ステップ.
UINT_PTR GetRaw(void) const
[取得] 列番号取得
TYP GetBlockChar(void) const
[取得] ブロック文字
CParts GetNextParts(bool boIsToken=true)
[取得] 次のパーツ取得
bool SkipoutBlock(void)
[処理] ブロックからステップアウト.
UINT_PTR GetPos(void) const
[取得] ポジション取得
CStr GetName(void) const
[取得] 名前取得
void SetName(LPCTSTR name)
[設定] 名前設定
CParts PeekNextParts(bool boIsToken=true)
[確認] 次のパーツ確認
CGrammarAnalyzerT(const CGrammarAnalyzerT &other)
コピーコンストラクタ
void SetFormat(const IFormat *P)
[設定] フォーマッタ設定.
文字列管理テンプレート
Definition: TnbStr.h:74
size_t GetLength(void) const
[取得] 文字列長
Definition: TnbStr.h:518
static CStrT Fmt(const TCHAR *lpszFormat,...)
[作成] 書式付き文字列作成
Definition: TnbStr.h:1206
void Empty(void)
[削除] 空化
Definition: TnbStr.h:197
CGrammarAnalyzerT CGrammarAnalyzer
文法解析クラス(ASCII/SJIS)
int GetCharSize(char c)
[取得] 文字のサイズ(ASCII/SJIS用)
Definition: TnbStrLib.h:341
TNB::CStrT< TCHAR > CStr
文字列クラス
Definition: TnbStr.h:1785
TNB Library
Definition: TnbDoxyTitle.txt:2
文法解析用フォーマットインターフェース
virtual bool IsTokenPeriodChar(TYP c) const
[確認] トークン区切り文字判定.
virtual bool IsBlankChar(TYP c) const
[確認] ブランク文字判定.
virtual ~IFormat(void)
デストラクタ
virtual bool IsStringMarkChar(TYP c) const
[確認] 文字列始終端文字チェック.
virtual bool IsEndChar(TYP c) const
[確認] 終端文字チェック 終端文字を定義するメソッドです。
virtual int CheckStringSpecialWord(CStrT< TYP > &_str, ITE ite) const
[取得] 文字列内特殊文字チェック.
virtual TYP CheckBlockStartChar(TYP c) const
[確認] 始端文字チェック.
virtual bool IsBlockCloseChar(TYP c) const
[確認] 終端文字チェック.
virtual int CheckComment(CStrT< TYP > &_str, ITE ite) const
[取得] コメントチェック.