Skip to content

Commit af6acfd

Browse files
committed
Add major re-factoring lexer in parser.hpp
More modular and hopefully better readable!
1 parent fdee463 commit af6acfd

File tree

1 file changed

+63
-105
lines changed

1 file changed

+63
-105
lines changed

parser.hpp

Lines changed: 63 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -72,42 +72,41 @@ namespace Sass {
7272
bool peek_newline(const char* start = 0);
7373

7474
template <prelexer mx>
75-
const char* peek(const char* start = 0)
75+
const char* sneak(const char* start = 0)
7676
{
77-
if (!start) start = position;
78-
const char* it_before_token;
79-
if (mx == block_comment) {
80-
it_before_token = // start;
81-
zero_plus< alternatives<spaces, line_comment> >(start);
82-
}
83-
else if (/*mx == ancestor_of ||*/ mx == no_spaces) {
84-
it_before_token = position;
85-
}
86-
else if (mx == spaces) {
87-
it_before_token = mx(start);
88-
if (it_before_token) {
89-
return it_before_token;
90-
}
91-
else {
92-
return 0;
93-
}
94-
}
95-
else if (mx == optional_spaces) {
96-
it_before_token = optional_spaces(start);
97-
}
98-
else if (mx == line_comment_prefix || mx == block_comment_prefix) {
99-
it_before_token = position;
100-
}
101-
else {
102-
it_before_token = optional_css_whitespace(start);
103-
}
104-
const char* it_after_token = mx(it_before_token);
105-
if (it_after_token) {
106-
return it_after_token;
107-
}
108-
else {
109-
return 0;
77+
78+
// maybe use optional start position from arguments?
79+
const char* it_before_token = start ? start : position;
80+
81+
// skip white-space?
82+
if (mx == url ||
83+
mx == spaces ||
84+
mx == no_spaces ||
85+
mx == css_comments ||
86+
mx == css_whitespace ||
87+
mx == optional_spaces ||
88+
mx == optional_css_comments ||
89+
mx == optional_css_whitespace
90+
) {
91+
return it_before_token;
11092
}
93+
94+
// skip over spaces, tabs and sass line comments
95+
return optional_css_whitespace(it_before_token);
96+
97+
}
98+
99+
template <prelexer mx>
100+
const char* peek(const char* start = 0)
101+
{
102+
103+
// sneak up to the actual token we want to lex
104+
// this should skip over white-space if desired
105+
const char* it_before_token = sneak < mx >(start);
106+
107+
// match the given prelexer
108+
return mx(it_before_token);
109+
111110
}
112111

113112
// white-space handling is built into the lexer
@@ -120,92 +119,51 @@ namespace Sass {
120119
// remeber interesting position
121120
const char* wspace_start = position;
122121

123-
// advance position for next call
124-
before_token = after_token;
125-
126-
// after optional whitespace
127-
const char* it_before_token;
128-
129-
if (mx == block_comment) {
130-
// a block comment can be preceded by spaces and/or line comments
131-
it_before_token = zero_plus< alternatives<spaces, line_comment> >(position);
132-
}
133-
else if (mx == url || mx == no_spaces) {
134-
// parse everything literally
135-
it_before_token = position;
136-
}
137-
138-
else if (mx == spaces) {
139-
it_before_token = spaces(position);
140-
if (it_before_token) {
141-
return position = it_before_token;
142-
}
143-
else {
144-
return 0;
145-
}
146-
}
147-
148-
else if (mx == css_comments ||
149-
mx == css_whitespace ||
150-
mx == optional_css_comments ||
151-
mx == optional_css_whitespace
152-
) {
153-
it_before_token = position;
154-
}
122+
// sneak up to the actual token we want to lex
123+
// this should skip over white-space if desired
124+
const char* it_before_token = sneak < mx >(position);
155125

156-
else if (mx == optional_spaces) {
157-
// ToDo: what are optiona_spaces ???
158-
it_before_token = optional_spaces(position);
159-
}
160-
else {
161-
// most can be preceded by spaces and comments
162-
it_before_token = optional_css_whitespace(position);
163-
}
126+
// advance position (add whitespace before current token)
127+
before_token = after_token.inc(position, it_before_token);
164128

165129
// now call matcher to get position after token
166130
const char* it_after_token = mx(it_before_token);
131+
167132
// assertion that we got a valid match
168133
if (it_after_token == 0) return 0;
169134

170-
// add whitespace after previous and before this token
171-
while (position < it_before_token && *position) {
172-
if (*position == '\n') {
173-
++ before_token.line;
174-
before_token.column = 0;
175-
} else {
176-
++ before_token.column;
177-
}
178-
++position;
179-
}
180-
181-
// copy position
182-
after_token = before_token;
183-
184-
Offset size(0, 0);
185-
186-
// increase position to include current token
187-
while (position < it_after_token && *position) {
188-
if (*position == '\n') {
189-
++ size.line;
190-
size.column = 0;
191-
} else {
192-
++ size.column;
193-
}
194-
++position;
195-
}
135+
// create new lexed token object (holds all parse result information)
136+
lexed = Token(wspace_start, it_before_token, it_after_token);
196137

197-
after_token = after_token + size;
138+
// update position of after_token (add token to before position)
139+
after_token = before_token.inc(it_before_token, it_after_token);
198140

199-
// create parsed token string (public member)
200-
lexed = Token(wspace_start, it_before_token, it_after_token);
201-
Position pos(before_token.file, before_token.line, before_token.column);
202-
pstate = ParserState(path, lexed, pos, size);
141+
// ToDo: could probably do this incremetal on original object
142+
pstate = ParserState(path, lexed, before_token, after_token - before_token);
203143

204144
// advance internal char iterator
205145
return position = it_after_token;
206146

207147
}
208148

149+
// skips over css comments
150+
template <prelexer mx>
151+
const char* lex_css()
152+
{
153+
// throw away comments
154+
lex < css_comments >();
155+
// now lex a token
156+
return lex< mx >();
157+
}
158+
159+
// skips over css comments
160+
template <prelexer mx>
161+
const char* peek_css()
162+
{
163+
// now peek a token (skip comments first)
164+
return peek< mx >(peek < css_comments >());
165+
}
166+
209167
#ifdef __clang__
210168

211169
#pragma clang diagnostic pop

0 commit comments

Comments
 (0)