-
Notifications
You must be signed in to change notification settings - Fork 0
/
IdentComments.cpp
131 lines (113 loc) · 2.5 KB
/
IdentComments.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// IdentComments.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <iterator>
#include <string>
using namespace std;
typedef string::const_iterator ParserPosition;
class ParserState
{
public:
ParserState() : m_needEndOfLine(false), m_firstLine(false), m_phase(&ParserState::StartPhase)
{}
void BeforeParseLine()
{
m_needEndOfLine = false;
}
ParserPosition Parse(ParserPosition begin, ParserPosition end)
{
return (*this.*m_phase)(begin, end);
}
void AfterParseLine()
{
if (m_needEndOfLine)
cout << endl;
}
private:
typedef ParserPosition(ParserState::*ParserPhase)(ParserPosition begin, ParserPosition end);
ParserPosition StartPhase(ParserPosition begin, ParserPosition end)
{
m_firstLine = false;
for (; begin != end; ++begin)
{
switch (*begin)
{
case '"':
m_phase = &ParserState::StringPhase;
return ++begin;
case '/':
if (++begin == end)
return begin;
if (*begin == '/')
{
m_phase = &ParserState::OneLineCommentPhase;
return --begin;
}
if (*begin == '*')
{
m_firstLine = true;
m_phase = &ParserState::MultilineCommentPhase;
return --begin;
}
break;
}
}
return end;
}
ParserPosition StringPhase(ParserPosition begin, ParserPosition end)
{
begin = find(begin, end, '"');
if (begin != end)
{
m_phase = &ParserState::StartPhase;
return ++begin;
}
return begin; // multiline string const
}
ParserPosition OneLineCommentPhase(ParserPosition begin, ParserPosition end)
{
m_needEndOfLine = true;
copy(begin, end, ostream_iterator<char>(cout));
m_phase = &ParserState::StartPhase;
return end;
}
ParserPosition MultilineCommentPhase(ParserPosition begin, ParserPosition end)
{
m_needEndOfLine = true;
for (auto needTrim = !m_firstLine; begin != end; ++begin)
{
if (!isspace(*begin) || !needTrim)
{
needTrim = false;
cout << *begin;
}
if (*begin == '*')
{
if (end != begin+1 && *(begin+1) == '/')
{
cout << *(++begin);
m_phase = &ParserState::StartPhase;
return ++begin;
}
}
}
m_firstLine = false;
return end;
}
private:
bool m_needEndOfLine;
bool m_firstLine;
ParserPhase m_phase;
};
int _tmain(int argc, _TCHAR* argv[])
{
ParserState parser;
for (string line; getline(cin, line);)
{
parser.BeforeParseLine();
for (auto position = line.cbegin(); position != line.cend(); position = parser.Parse(position, line.cend()));
parser.AfterParseLine();
}
return 0;
}