Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
N
node-sass
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
楚学文
node-sass
Commits
71c31368
Commit
71c31368
authored
Mar 06, 2012
by
Aaron Leung
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Improving the node struct, and working on new parsing functionaity.
parent
9a893f9d
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
256 additions
and
160 deletions
+256
-160
document.hpp
document.hpp
+5
-4
document_parser.cpp
document_parser.cpp
+55
-31
node.cpp
node.cpp
+44
-46
node.hpp
node.hpp
+132
-79
token.cpp
token.cpp
+17
-0
token.hpp
token.hpp
+3
-0
No files found.
document.hpp
View file @
71c31368
...
@@ -12,10 +12,10 @@ namespace Sass {
...
@@ -12,10 +12,10 @@ namespace Sass {
char
*
path
;
char
*
path
;
char
*
source
;
char
*
source
;
char
*
position
;
char
*
position
;
unsigned
in
t
line_number
;
size_
t
line_number
;
// TO DO: move the environment up into the context class when it's ready
// TO DO: move the environment up into the context class when it's ready
map
<
string
,
Node
>
environment
;
map
<
Token
,
Node
>
environment
;
vector
<
Node
>
statements
;
vector
<
Node
>
statements
;
Token
top
;
Token
top
;
...
@@ -24,7 +24,8 @@ namespace Sass {
...
@@ -24,7 +24,8 @@ namespace Sass {
Document
(
char
*
_path
,
char
*
_source
=
0
);
Document
(
char
*
_path
,
char
*
_source
=
0
);
~
Document
();
~
Document
();
inline
Token
&
peek
()
{
return
top
;
}
template
<
prelexer
mx
>
char
*
peek
()
{
return
mx
(
position
);
}
template
<
prelexer
mx
>
template
<
prelexer
mx
>
bool
try_munching
()
{
bool
try_munching
()
{
...
@@ -68,7 +69,7 @@ namespace Sass {
...
@@ -68,7 +69,7 @@ namespace Sass {
Node
parse_var_def
();
Node
parse_var_def
();
Node
parse_ruleset
();
Node
parse_ruleset
();
Node
parse_selector
();
Node
parse_selector
();
Node
parse_
clauses
();
Node
parse_
block
();
Node
parse_values
();
Node
parse_values
();
string
emit_css
(
CSS_Style
style
);
string
emit_css
(
CSS_Style
style
);
...
...
document_parser.cpp
View file @
71c31368
...
@@ -3,88 +3,112 @@
...
@@ -3,88 +3,112 @@
namespace
Sass
{
namespace
Sass
{
void
Document
::
parse_scss
()
{
void
Document
::
parse_scss
()
{
try_munching
<
optional_spaces
>
();
// try_munching<optional_spaces>();
while
(
*
position
)
{
// while (*position) {
// statements.push_back(parse_statement());
// try_munching<optional_spaces>();
// }
lex
<
optional_spaces
>
();
while
(
*
position
)
{
statements
.
push_back
(
parse_statement
());
statements
.
push_back
(
parse_statement
());
try_munching
<
optional_spaces
>
();
lex
<
optional_spaces
>
();
}
}
}
}
Node
Document
::
parse_statement
()
{
Node
Document
::
parse_statement
()
{
if
(
try_munching
<
block_comment
>
())
{
// if (try_munching<block_comment>()) {
return
Node
(
Node
::
comment
,
top
);
// return Node(line_number, Node::comment, top);
// }
// else if (try_munching<variable>()) {
// return parse_var_def();
// }
// else return parse_ruleset();
if
(
lex
<
block_comment
>
())
{
return
Node
(
line_number
,
Node
::
comment
,
lexed
);
}
}
else
if
(
try_munching
<
variable
>
())
{
else
if
(
lex
<
variable
>
())
{
return
parse_var_def
();
return
parse_var_def
();
}
}
else
return
parse_ruleset
();
else
return
parse_ruleset
();
}
}
Node
Document
::
parse_var_def
()
{
Node
Document
::
parse_var_def
()
{
const
Token
key
=
top
;
// const Token key(top);
try_munching
<
exactly
<
':'
>
>
();
// try_munching<exactly<':'> >();
environment
[
string
(
key
)]
=
parse_values
();
// environment[key] = parse_values();
try_munching
<
exactly
<
';'
>
>
();
// try_munching<exactly<';'> >();
return
Node
(
Node
::
nil
);
// return Node(line_number, Node::nil, top);
const
Token
key
(
lexed
);
lex
<
exactly
<
':'
>
>
();
environment
[
key
]
=
parse_values
();
lex
<
exactly
<
';'
>
>
();
return
Node
();
}
}
Node
Document
::
parse_ruleset
()
{
Node
Document
::
parse_ruleset
()
{
Node
ruleset
(
Node
::
ruleset
);
Node
ruleset
(
line_number
,
Node
::
ruleset
,
2
);
ruleset
.
push_child
(
parse_selector
()
);
ruleset
<<
parse_selector
(
);
ruleset
.
push_child
(
parse_clauses
()
);
ruleset
<<
parse_block
(
);
return
ruleset
;
return
ruleset
;
}
}
Node
Document
::
parse_selector
()
{
Node
Document
::
parse_selector
()
{
try_munching
<
identifier
>
();
try_munching
<
identifier
>
();
return
Node
(
Node
::
selector
,
top
);
return
Node
(
line_number
,
Node
::
selector
,
top
);
}
}
Node
Document
::
parse_
clauses
()
{
Node
Document
::
parse_
block
()
{
try_munching
<
exactly
<
'{'
>
>
();
try_munching
<
exactly
<
'{'
>
>
();
Node
decls
(
Node
::
clauses
);
Node
decls
(
line_number
,
Node
::
block
);
while
(
!
try_munching
<
exactly
<
'}'
>
>
())
{
while
(
!
try_munching
<
exactly
<
'}'
>
>
())
{
if
(
try_munching
<
block_comment
>
())
{
if
(
try_munching
<
block_comment
>
())
{
decls
.
push_child
(
Node
(
Node
::
comment
,
top
)
);
decls
<<
Node
(
line_number
,
Node
::
comment
,
top
);
continue
;
continue
;
}
}
else
if
(
try_munching
<
variable
>
())
{
else
if
(
try_munching
<
variable
>
())
{
decls
.
push_child
(
parse_var_def
()
);
decls
<<
parse_var_def
(
);
continue
;
continue
;
}
}
try_munching
<
identifier
>
();
try_munching
<
identifier
>
();
Token
id
=
top
;
Token
id
=
top
;
if
(
try_munching
<
exactly
<
':'
>
>
())
{
if
(
try_munching
<
exactly
<
':'
>
>
())
{
Node
rule
(
Node
::
rule
);
Node
rule
(
line_number
,
Node
::
rule
,
2
);
rule
.
push_child
(
Node
(
Node
::
property
,
id
));
rule
<<
Node
(
line_number
,
Node
::
property
,
id
);
rule
.
push_child
(
parse_values
());
rule
<<
parse_values
();
decls
.
push_child
(
rule
);
decls
<<
rule
;
decls
.
has_rules
=
true
;
try_munching
<
exactly
<
';'
>
>
();
try_munching
<
exactly
<
';'
>
>
();
}
}
else
{
else
{
Node
ruleset
(
Node
::
ruleset
);
Node
ruleset
(
line_number
,
Node
::
ruleset
,
2
);
ruleset
.
push_child
(
Node
(
Node
::
selector
,
id
));
ruleset
<<
Node
(
line_number
,
Node
::
selector
,
id
);
ruleset
.
push_child
(
parse_clauses
());
ruleset
<<
parse_block
();
decls
.
push_opt_child
(
ruleset
);
decls
<<
ruleset
;
decls
.
has_rulesets
=
true
;
}
}
}
}
return
decls
;
return
decls
;
}
}
Node
Document
::
parse_values
()
{
Node
Document
::
parse_values
()
{
Node
values
(
Node
::
values
);
Node
values
(
line_number
,
Node
::
values
);
while
(
try_munching
<
identifier
>
()
||
try_munching
<
dimension
>
()
||
while
(
try_munching
<
identifier
>
()
||
try_munching
<
dimension
>
()
||
try_munching
<
percentage
>
()
||
try_munching
<
number
>
()
||
try_munching
<
percentage
>
()
||
try_munching
<
number
>
()
||
try_munching
<
hex
>
()
||
try_munching
<
string_constant
>
()
||
try_munching
<
hex
>
()
||
try_munching
<
string_constant
>
()
||
try_munching
<
variable
>
())
{
try_munching
<
variable
>
())
{
if
(
top
.
begin
[
0
]
==
'$'
)
{
if
(
top
.
begin
[
0
]
==
'$'
)
{
Node
stuff
(
environment
[
string
(
top
)
]);
Node
stuff
(
environment
[
top
]);
for
(
int
i
=
0
;
i
<
stuff
.
children
->
size
();
++
i
)
{
for
(
int
i
=
0
;
i
<
stuff
.
children
->
size
();
++
i
)
{
values
.
push_child
((
*
(
stuff
.
children
))[
i
]
);
values
<<
stuff
.
children
->
at
(
i
);
}
}
}
}
else
else
values
.
push_child
(
Node
(
Node
::
value
,
top
));
{
values
<<
Node
(
line_number
,
Node
::
value
,
top
);
}
}
}
return
values
;
return
values
;
}
}
...
...
node.cpp
View file @
71c31368
...
@@ -5,43 +5,44 @@
...
@@ -5,43 +5,44 @@
using
std
::
string
;
using
std
::
string
;
using
std
::
stringstream
;
using
std
::
stringstream
;
using
std
::
cout
;
using
std
::
cout
;
using
std
::
cerr
;
using
std
::
endl
;
using
std
::
endl
;
namespace
Sass
{
namespace
Sass
{
unsigned
in
t
Node
::
fresh
=
0
;
size_
t
Node
::
fresh
=
0
;
unsigned
in
t
Node
::
copied
=
0
;
size_
t
Node
::
copied
=
0
;
Node
::
Node
()
{
++
fresh
;
children
=
0
;
opt_children
=
0
;
}
//
Node::Node() { ++fresh; children = 0; opt_children = 0; }
Node
::
Node
(
Node_Type
_type
)
{
//
Node::Node(Node_Type _type) {
type
=
_type
;
//
type = _type;
children
=
new
vector
<
Node
>
;
//
children = new vector<Node>;
opt_children
=
new
vector
<
Node
>
;
//
opt_children = new vector<Node>;
++
fresh
;
//
++fresh;
}
//
}
Node
::
Node
(
Node_Type
_type
,
Token
&
_token
)
{
//
Node::Node(Node_Type _type, Token& _token) {
type
=
_type
;
//
type = _type;
token
=
_token
;
//
token = _token;
children
=
0
;
//
children = 0;
opt_children
=
0
;
//
opt_children = 0;
++
fresh
;
//
++fresh;
}
//
}
Node
::
Node
(
const
Node
&
n
)
{
//
Node::Node(const Node& n) {
type
=
n
.
type
;
//
type = n.type;
token
=
n
.
token
;
//
token = n.token;
children
=
n
.
children
;
//
children = n.children;
opt_children
=
n
.
opt_children
;
//
opt_children = n.opt_children;
++
copied
;
//
++copied;
}
//
}
//
void
Node
::
push_child
(
const
Node
&
node
)
{
//
void Node::push_child(const Node& node) {
if
(
!
children
)
children
=
new
vector
<
Node
>
;
//
if (!children) children = new vector<Node>;
children
->
push_back
(
node
);
//
children->push_back(node);
}
//
}
void
Node
::
push_opt_child
(
const
Node
&
node
)
{
//
void Node::push_opt_child(const Node& node) {
if
(
!
opt_children
)
opt_children
=
new
vector
<
Node
>
;
//
if (!opt_children) opt_children = new vector<Node>;
opt_children
->
push_back
(
node
);
//
opt_children->push_back(node);
}
//
}
void
Node
::
dump
(
unsigned
int
depth
)
{
//
void Node::dump(unsigned int depth) {
// switch (type) {
// switch (type) {
// case comment:
// case comment:
// for (int i = depth; i > 0; --i) cout << " ";
// for (int i = depth; i > 0; --i) cout << " ";
...
@@ -84,35 +85,32 @@ namespace Sass {
...
@@ -84,35 +85,32 @@ namespace Sass {
// break;
// break;
// default: cout << "HUH?"; break;
// default: cout << "HUH?"; break;
// }
// }
}
//
}
void
Node
::
emit_nested_css
(
stringstream
&
buf
,
void
Node
::
emit_nested_css
(
stringstream
&
buf
,
const
string
&
prefix
,
const
string
&
prefix
,
size_t
depth
)
{
size_t
depth
)
{
string
indentation
(
2
*
depth
,
' '
);
string
indentation
(
2
*
depth
,
' '
);
bool
has_rules
,
has_nested_ruleset
s
;
vector
<
Node
>*
node
s
;
if
(
type
==
ruleset
)
{
if
(
type
==
ruleset
)
{
// has_rules = !((*children)[1].children->empty());
nodes
=
children
->
at
(
1
).
children
;
has_rules
=
!
(
children
->
at
(
1
).
children
->
empty
());
has_rules
=
children
->
at
(
1
).
has_rules
;
// has_nested_rulesets = !((*children)[1].opt_children->empty());
has_rulesets
=
children
->
at
(
1
).
has_rulesets
;
has_nested_rulesets
=
!
(
children
->
at
(
1
).
opt_children
->
empty
());
}
}
switch
(
type
)
{
switch
(
type
)
{
case
ruleset
:
case
ruleset
:
if
(
has_rules
)
{
if
(
has_rules
)
{
buf
<<
indentation
;
buf
<<
indentation
;
// (*children)[0].emit_nested_css(buf, prefix, depth); // selector
children
->
at
(
0
).
emit_nested_css
(
buf
,
prefix
,
depth
);
// selector
children
->
at
(
0
).
emit_nested_css
(
buf
,
prefix
,
depth
);
// selector
buf
<<
" {"
;
buf
<<
" {"
;
for
(
int
i
=
0
;
i
<
(
*
children
)[
1
].
children
->
size
();
++
i
)
{
for
(
int
i
=
0
;
i
<
nodes
->
size
();
++
i
)
{
// (*(*children)[1].children)[i].emit_nested_css(buf, "", depth + 1); // rules
if
(
nodes
->
at
(
i
).
type
==
rule
)
nodes
->
at
(
i
).
emit_nested_css
(
buf
,
""
,
depth
+
1
);
// rules
children
->
at
(
1
).
children
->
at
(
i
).
emit_nested_css
(
buf
,
""
,
depth
+
1
);
// rules
}
}
buf
<<
" }"
<<
endl
;
buf
<<
" }"
<<
endl
;
}
}
if
(
has_
nested_
rulesets
)
{
if
(
has_rulesets
)
{
for
(
int
i
=
0
;
i
<
children
->
at
(
1
).
opt_children
->
size
();
++
i
)
{
// do each nested ruleset
for
(
int
i
=
0
;
i
<
nodes
->
size
();
++
i
)
{
// do each nested ruleset
children
->
at
(
1
).
opt_children
->
at
(
i
).
emit_nested_css
(
buf
,
prefix
+
(
prefix
.
empty
()
?
""
:
" "
)
+
string
((
*
children
)[
0
].
token
),
depth
+
(
has_rules
?
1
:
0
));
if
(
nodes
->
at
(
i
).
type
==
ruleset
)
nodes
->
at
(
i
).
emit_nested_css
(
buf
,
prefix
+
(
prefix
.
empty
()
?
""
:
" "
)
+
string
((
*
children
)[
0
].
token
),
depth
+
(
has_rules
?
1
:
0
));
}
}
}
}
if
(
depth
==
0
&&
prefix
.
empty
())
buf
<<
endl
;
if
(
depth
==
0
&&
prefix
.
empty
())
buf
<<
endl
;
...
...
node.hpp
View file @
71c31368
...
@@ -6,102 +6,156 @@ namespace Sass {
...
@@ -6,102 +6,156 @@ namespace Sass {
using
std
::
vector
;
using
std
::
vector
;
using
std
::
stringstream
;
using
std
::
stringstream
;
// struct Node {
// enum Node_Type {
// nil,
// comment,
// ruleset,
// clauses,
// selector_group,
// selector,
// simple_selector_sequence,
// simple_selector,
// rule,
// property,
// values,
// value
// };
//
// static unsigned int fresh;
// static unsigned int copied;
//
// Node_Type type;
// Token token;
// vector<Node>* children;
// vector<Node>* opt_children;
//
// Node();
// Node(Node_Type _type);
// Node(Node_Type _type, Token& _token);
// Node(const Node& n);
//
// void push_child(const Node& node);
// void push_opt_child(const Node& node);
// void dump(unsigned int depth = 0);
// void emit_nested_css(stringstream& buf, const string& prefix, size_t depth);
// void emit_expanded_css(stringstream& buf, const string& prefix);
// };
struct
Node
{
struct
Node
{
enum
Node_
Type
{
enum
Type
{
nil
,
nil
,
comment
,
comment
,
ruleset
,
ruleset
,
clauses
,
propset
,
selector_group
,
selector_group
,
selector
,
selector
,
simple_selector_sequence
,
simple_selector_sequence
,
simple_selector
,
type_selector
,
class_selector
,
id_selector
,
attribute_selector
,
block
,
rule
,
rule
,
property
,
property
,
values
,
values
,
value
value
};
};
static
unsigned
in
t
fresh
;
static
size_
t
fresh
;
static
unsigned
in
t
copied
;
static
size_
t
copied
;
Node_Type
type
;
size_t
line_number
;
mutable
vector
<
Node
>*
children
;
Token
token
;
Token
token
;
vector
<
Node
>*
children
;
Type
type
;
vector
<
Node
>*
opt_children
;
bool
has_rules
;
bool
has_rulesets
;
bool
has_propsets
;
Node
()
{
++
fresh
;
}
Node
(
const
Node
&
n
)
:
line_number
(
n
.
line_number
),
children
(
n
.
children
),
token
(
n
.
token
),
type
(
n
.
type
),
has_rules
(
n
.
has_rules
),
has_rulesets
(
n
.
has_rulesets
),
has_propsets
(
n
.
has_propsets
)
{
/*n.release();*/
++
copied
;
}
// No joint custody.
Node
(
size_t
line_number
,
Type
type
,
size_t
length
=
0
)
:
line_number
(
line_number
),
children
(
new
vector
<
Node
>
),
token
(
Token
()),
type
(
type
),
has_rules
(
false
),
has_rulesets
(
false
),
has_propsets
(
false
)
{
children
->
reserve
(
length
);
++
fresh
;
}
Node
(
size_t
line_number
,
Type
type
,
const
Node
&
n
)
:
line_number
(
line_number
),
children
(
new
vector
<
Node
>
(
1
,
n
)),
token
(
Token
()),
type
(
type
),
has_rules
(
false
),
has_rulesets
(
false
),
has_propsets
(
false
)
{
++
fresh
;
}
Node
(
size_t
line_number
,
Type
type
,
const
Node
&
n
,
const
Node
&
m
)
:
line_number
(
line_number
),
children
(
new
vector
<
Node
>
),
token
(
Token
()),
type
(
type
),
has_rules
(
false
),
has_rulesets
(
false
),
has_propsets
(
false
)
{
children
->
reserve
(
2
);
children
->
push_back
(
n
);
children
->
push_back
(
m
);
++
fresh
;
}
Node
(
size_t
line_number
,
Type
type
,
Token
&
token
)
:
line_number
(
line_number
),
children
(
0
),
token
(
token
),
type
(
type
),
has_rules
(
false
),
has_rulesets
(
false
),
has_propsets
(
false
)
{
++
fresh
;
}
Node
();
//~Node() { delete children; }
Node
(
Node_Type
_type
);
Node
(
Node_Type
_type
,
Token
&
_token
);
Node
&
operator
=
(
const
Node
&
n
)
Node
(
const
Node
&
n
);
{
line_number
=
n
.
line_number
;
children
=
n
.
children
;
// n.release();
token
=
n
.
token
;
type
=
n
.
type
;
has_rules
=
n
.
has_rules
;
has_rulesets
=
n
.
has_rulesets
;
has_propsets
=
n
.
has_propsets
;
++
copied
;
return
*
this
;
}
// Node& operator+=(const Node& node);
Node
&
operator
<<
(
const
Node
&
n
)
{
children
->
push_back
(
n
);
return
*
this
;
}
void
release
()
const
{
children
=
0
;
}
void
push_child
(
const
Node
&
node
);
void
push_opt_child
(
const
Node
&
node
);
void
dump
(
unsigned
int
depth
=
0
);
void
emit_nested_css
(
stringstream
&
buf
,
const
string
&
prefix
,
size_t
depth
);
void
emit_nested_css
(
stringstream
&
buf
,
const
string
&
prefix
,
size_t
depth
);
void
emit_expanded_css
(
stringstream
&
buf
,
const
string
&
prefix
);
void
emit_expanded_css
(
stringstream
&
buf
,
const
string
&
prefix
);
};
};
// struct Node {
// enum Type {
// nil,
// comment,
// ruleset,
// selector_group,
// selector,
// simple_selector_sequence,
// type_selector,
// class_selector,
// id_selector,
// attribute_selector,
// clauses,
// rule,
// property,
// values,
// value
// };
//
// size_t line_number;
// mutable vector<Node>* children;
// Token token;
// Type type;
// bool has_rules;
// bool has_rulesets;
// bool has_nested_properties;
//
// Node(const Node& n)
// : line_number(n.line_number),
// children(n.children),
// token(n.token),
// type(n.type),
// has_rules(n.has_rules),
// has_rulesets(n.has_rulesets),
// has_nested_properties(n.has_nested_properties)
// { n.release(); } // No joint custody.
//
// Node(size_t line_number, Type type, size_t length = 0)
// : line_number(line_number),
// children(new vector<Node>),
// token(Token()),
// type(type),
// has_rules(false),
// has_rulesets(false),
// has_nested_properties(false)
// { children->reserve(length); }
//
// Node(size_t line_number, Type type, Token& token)
// : line_number(line_number),
// children(0),
// token(token),
// type(type),
// has_rules(false),
// has_rulesets(false),
// has_nested_properties(false)
// { }
//
// Node& operator=(const Node& node);
// Node& operator+=(const Node& node);
// Node& operator<<(const Node& node);
// void release() const { children = 0; }
// };
}
}
\ No newline at end of file
token.cpp
View file @
71c31368
...
@@ -40,4 +40,20 @@ namespace Sass {
...
@@ -40,4 +40,20 @@ namespace Sass {
return
;
return
;
}
}
}
}
using
std
::
lexicographical_compare
;
bool
Token
::
operator
<
(
const
Token
&
rhs
)
const
{
const
char
*
first1
=
begin
;
const
char
*
last1
=
end
;
const
char
*
first2
=
rhs
.
begin
;
const
char
*
last2
=
rhs
.
end
;
while
(
first1
!=
last1
)
{
if
(
first2
==
last2
||
*
first2
<*
first1
)
return
false
;
else
if
(
*
first1
<*
first2
)
return
true
;
first1
++
;
first2
++
;
}
return
(
first2
!=
last2
);
}
}
}
\ No newline at end of file
token.hpp
View file @
71c31368
...
@@ -21,5 +21,7 @@ namespace Sass {
...
@@ -21,5 +21,7 @@ namespace Sass {
void
stream_unquoted
(
std
::
stringstream
&
buf
)
const
;
void
stream_unquoted
(
std
::
stringstream
&
buf
)
const
;
bool
operator
<
(
const
Token
&
rhs
)
const
;
};
};
}
}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment