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
ea68a55e
Commit
ea68a55e
authored
May 22, 2012
by
Aaron Leung
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Pushing the Node refactor through the parser.
parent
d0ca3362
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
178 additions
and
262 deletions
+178
-262
document_parser.cpp
document_parser.cpp
+178
-262
No files found.
document_parser.cpp
View file @
ea68a55e
...
@@ -5,38 +5,27 @@
...
@@ -5,38 +5,27 @@
namespace
Sass
{
namespace
Sass
{
using
namespace
std
;
using
namespace
std
;
extern
const
char
plus_equal
[]
=
"+="
;
//
extern const char plus_equal[] = "+=";
void
Document
::
parse_scss
()
void
Document
::
parse_scss
()
{
{
lex
<
optional_spaces
>
();
lex
<
optional_spaces
>
();
root
<<
Node
(
Node
::
flags
);
while
(
position
<
end
)
{
while
(
position
<
end
)
{
if
(
lex
<
block_comment
>
())
{
if
(
lex
<
block_comment
>
())
{
root
<<
Node
(
Node
::
comment
,
line_number
,
lexed
);
root
<<
context
.
new_Node
(
Node
::
comment
,
path
,
line_number
,
lexed
);
}
}
else
if
(
peek
<
import
>
(
position
))
{
else
if
(
peek
<
import
>
())
{
// TO DO: don't splice in place at parse-time -- use an expansion node
Node
importee
(
parse_import
());
Node
import
(
parse_import
());
if
(
importee
.
type
()
==
Node
::
css_import
)
root
<<
importee
;
if
(
import
.
type
==
Node
::
css_import
)
{
else
root
+=
importee
;
root
<<
import
;
if
(
!
lex
<
exactly
<
';'
>
>
())
throw_syntax_error
(
"top-level @import directive must be terminated by ';'"
);
}
else
{
root
+=
import
;
}
if
(
!
lex
<
exactly
<
';'
>
>
())
syntax_error
(
"top-level @import directive must be terminated by ';'"
);
}
}
else
if
(
peek
<
mixin
>
(
position
)
||
peek
<
exactly
<
'='
>
>
(
position
))
{
else
if
(
peek
<
mixin
>
(
)
||
peek
<
exactly
<
'='
>
>
(
))
{
root
<<
parse_mixin_definition
();
root
<<
parse_mixin_definition
();
}
}
else
if
(
peek
<
include
>
(
position
))
{
else
if
(
peek
<
variable
>
())
{
root
<<
parse_mixin_call
();
root
[
0
].
has_expansions
=
true
;
if
(
!
lex
<
exactly
<
';'
>
>
())
syntax_error
(
"top-level @include directive must be terminated by ';'"
);
}
else
if
(
peek
<
variable
>
(
position
))
{
root
<<
parse_assignment
();
root
<<
parse_assignment
();
if
(
!
lex
<
exactly
<
';'
>
>
())
syntax_error
(
"top-level variable binding must be terminated by ';'"
);
if
(
!
lex
<
exactly
<
';'
>
>
())
throw_
syntax_error
(
"top-level variable binding must be terminated by ';'"
);
}
}
else
if
(
peek
<
sequence
<
identifier
,
optional_spaces
,
exactly
<
':'
>
,
optional_spaces
,
exactly
<
'{'
>
>
>
(
position
))
{
else
if
(
peek
<
sequence
<
identifier
,
optional_spaces
,
exactly
<
':'
>
,
optional_spaces
,
exactly
<
'{'
>
>
>
(
position
))
{
root
<<
parse_propset
();
root
<<
parse_propset
();
...
@@ -44,16 +33,15 @@ namespace Sass {
...
@@ -44,16 +33,15 @@ namespace Sass {
else
if
(
lookahead_for_selector
(
position
))
{
else
if
(
lookahead_for_selector
(
position
))
{
root
<<
parse_ruleset
();
root
<<
parse_ruleset
();
}
}
else
if
(
peek
<
exactly
<
'+'
>
>
())
{
else
if
(
peek
<
include
>
()
||
peek
<
exactly
<
'+'
>
>
())
{
root
<<
parse_mixin_call
();
root
<<
parse_mixin_call
();
root
[
0
].
has_expansions
=
true
;
if
(
!
lex
<
exactly
<
';'
>
>
())
throw_syntax_error
(
"top-level @include directive must be terminated by ';'"
);
if
(
!
lex
<
exactly
<
';'
>
>
())
syntax_error
(
"top-level @include directive must be terminated by ';'"
);
}
}
else
{
else
{
lex
<
spaces_and_comments
>
();
lex
<
spaces_and_comments
>
();
syntax_error
(
"invalid top-level expression"
);
syntax_error
(
"invalid top-level expression"
);
}
}
lex
<
optional_spaces
>
();
lex
<
optional_spaces
>
();
}
}
}
}
...
@@ -64,24 +52,24 @@ namespace Sass {
...
@@ -64,24 +52,24 @@ namespace Sass {
{
{
if
(
peek
<
string_constant
>
())
{
if
(
peek
<
string_constant
>
())
{
Node
schema
(
parse_string
());
Node
schema
(
parse_string
());
Node
import
(
Node
::
css_import
,
context
.
registry
,
line_number
,
1
);
Node
import
ee
(
context
.
new_Node
(
Node
::
css_import
,
path
,
line_number
,
1
)
);
import
<<
schema
;
import
ee
<<
schema
;
if
(
!
lex
<
exactly
<
')'
>
>
())
syntax_error
(
"unterminated url in @import directive"
);
if
(
!
lex
<
exactly
<
')'
>
>
())
throw_
syntax_error
(
"unterminated url in @import directive"
);
return
import
;
return
import
ee
;
}
}
else
{
else
{
const
char
*
beg
=
position
;
const
char
*
beg
=
position
;
const
char
*
end
=
find_first
<
exactly
<
')'
>
>
(
position
);
const
char
*
end
=
find_first
<
exactly
<
')'
>
>
(
position
);
if
(
!
end
)
syntax_error
(
"unterminated url in @import directive"
);
if
(
!
end
)
throw_
syntax_error
(
"unterminated url in @import directive"
);
Node
path
(
Node
::
identifier
,
line_number
,
Token
::
make
(
beg
,
end
));
Node
path
(
context
.
new_Node
(
Node
::
identifier
,
path
,
line_number
,
Token
::
make
(
beg
,
end
)
));
Node
import
(
Node
::
css_import
,
context
.
registry
,
line_number
,
1
);
Node
import
ee
(
context
.
new_Node
(
Node
::
css_import
,
path
,
line_number
,
1
);
import
<<
path
;
import
ee
<<
path
;
position
=
end
;
position
=
end
;
lex
<
exactly
<
')'
>
>
();
lex
<
exactly
<
')'
>
>
();
return
import
;
return
import
ee
;
}
}
}
}
if
(
!
lex
<
string_constant
>
())
syntax_error
(
"@import directive requires a url or quoted path"
);
if
(
!
lex
<
string_constant
>
())
throw_
syntax_error
(
"@import directive requires a url or quoted path"
);
// TO DO: BETTER PATH HANDLING
// TO DO: BETTER PATH HANDLING
// cerr << "Importing " << lexed.to_string() << endl;
// cerr << "Importing " << lexed.to_string() << endl;
string
import_path
(
lexed
.
unquote
());
string
import_path
(
lexed
.
unquote
());
...
@@ -89,88 +77,93 @@ namespace Sass {
...
@@ -89,88 +77,93 @@ namespace Sass {
const
char
*
curr_path_end
=
folders
(
curr_path_start
);
const
char
*
curr_path_end
=
folders
(
curr_path_start
);
string
current_path
(
curr_path_start
,
curr_path_end
-
curr_path_start
);
string
current_path
(
curr_path_start
,
curr_path_end
-
curr_path_start
);
try
{
try
{
Document
importee
(
current_path
+
import_path
,
context
);
// Document importee(current_path + import_path, context);
Document
importee
(
Document
::
make_from_file
(
context
,
current_path
+
import_path
));
importee
.
parse_scss
();
importee
.
parse_scss
();
// cerr << "Finished parsing import " << lexed.to_string() << endl;
// cerr << "Finished parsing import " << lexed.to_string() << endl;
return
importee
.
root
;
return
importee
.
root
;
}
}
catch
(
string
&
path
)
{
catch
(
string
&
path
)
{
read_error
(
"error reading file
\"
"
+
path
+
"
\"
"
);
throw_
read_error
(
"error reading file
\"
"
+
path
+
"
\"
"
);
}
}
// unreached statement
// unreached statement
return
Node
(
Node
::
none
);
return
Node
(
);
}
}
Node
Document
::
parse_mixin_definition
()
Node
Document
::
parse_mixin_definition
()
{
{
lex
<
mixin
>
()
||
lex
<
exactly
<
'='
>
>
();
lex
<
mixin
>
()
||
lex
<
exactly
<
'='
>
>
();
if
(
!
lex
<
identifier
>
())
syntax_error
(
"invalid name in @mixin directive"
);
if
(
!
lex
<
identifier
>
())
throw_
syntax_error
(
"invalid name in @mixin directive"
);
Node
name
(
Node
::
identifier
,
line_number
,
lexed
);
Node
name
(
context
.
new_Node
(
Node
::
identifier
,
path
,
line_number
,
lexed
)
);
Node
params
(
parse_mixin_parameters
());
Node
params
(
parse_mixin_parameters
());
if
(
!
peek
<
exactly
<
'{'
>
>
())
syntax_error
(
"body for mixin "
+
name
.
content
.
token
.
to_string
()
+
" must begin with a '{'"
);
if
(
!
peek
<
exactly
<
'{'
>
>
())
throw_syntax_error
(
"body for mixin "
+
name
.
token
()
.
to_string
()
+
" must begin with a '{'"
);
Node
body
(
parse_block
(
true
));
Node
body
(
parse_block
(
true
));
Node
mixin
(
Node
::
mixin
,
context
.
registry
,
line_number
,
3
);
Node
the_mixin
(
context
.
new_Node
(
Node
::
mixin
,
path
,
line_number
,
3
);
mixin
<<
name
<<
params
<<
body
;
the_
mixin
<<
name
<<
params
<<
body
;
return
mixin
;
return
mixin
;
}
}
Node
Document
::
parse_mixin_parameters
()
Node
Document
::
parse_mixin_parameters
()
{
{
Node
params
(
Node
::
parameters
,
context
.
registry
,
line_number
);
Node
params
(
context
.
new_Node
(
Node
::
parameters
,
path
,
line_number
,
0
);
Token
name
(
lexed
);
Token
name
(
lexed
);
if
(
lex
<
exactly
<
'('
>
>
())
{
if
(
lex
<
exactly
<
'('
>
>
())
{
if
(
peek
<
variable
>
())
{
if
(
peek
<
variable
>
())
{
params
<<
parse_parameter
();
params
<<
parse_parameter
();
while
(
lex
<
exactly
<
','
>
>
())
{
while
(
lex
<
exactly
<
','
>
>
())
{
if
(
!
peek
<
variable
>
())
syntax_error
(
"expected a variable name (e.g. $x) for the parameter list for "
+
name
.
to_string
());
if
(
!
peek
<
variable
>
())
throw_
syntax_error
(
"expected a variable name (e.g. $x) for the parameter list for "
+
name
.
to_string
());
params
<<
parse_parameter
();
params
<<
parse_parameter
();
}
}
if
(
!
lex
<
exactly
<
')'
>
>
())
syntax_error
(
"parameter list for "
+
name
.
to_string
()
+
" requires a ')'"
);
if
(
!
lex
<
exactly
<
')'
>
>
())
throw_
syntax_error
(
"parameter list for "
+
name
.
to_string
()
+
" requires a ')'"
);
}
}
else
if
(
!
lex
<
exactly
<
')'
>
>
())
syntax_error
(
"expected a variable name (e.g. $x) or ')' for the parameter list for "
+
name
.
to_string
());
else
if
(
!
lex
<
exactly
<
')'
>
>
())
throw_
syntax_error
(
"expected a variable name (e.g. $x) or ')' for the parameter list for "
+
name
.
to_string
());
}
}
return
params
;
return
params
;
}
}
Node
Document
::
parse_parameter
()
{
Node
Document
::
parse_parameter
()
{
lex
<
variable
>
();
lex
<
variable
>
();
Node
var
(
Node
::
variable
,
line_number
,
lexed
);
Node
var
(
context
.
new_Node
(
Node
::
variable
,
path
,
line_number
,
lexed
)
);
if
(
lex
<
exactly
<
':'
>
>
())
{
// default value
if
(
lex
<
exactly
<
':'
>
>
())
{
// default value
Node
val
(
parse_space_list
());
Node
val
(
parse_space_list
());
Node
par_and_val
(
Node
::
assignment
,
context
.
registry
,
line_number
,
2
);
Node
par_and_val
(
context
.
new_Node
(
Node
::
assignment
,
path
,
line_number
,
2
)
);
par_and_val
<<
var
<<
val
;
par_and_val
<<
var
<<
val
;
return
par_and_val
;
return
par_and_val
;
}
}
else
{
else
{
return
var
;
return
var
;
}
}
// unreachable statement
return
Node
();
}
}
Node
Document
::
parse_mixin_call
()
Node
Document
::
parse_mixin_call
()
{
{
lex
<
include
>
()
||
lex
<
exactly
<
'+'
>
>
();
lex
<
include
>
()
||
lex
<
exactly
<
'+'
>
>
();
if
(
!
lex
<
identifier
>
())
syntax_error
(
"invalid name in @include directive"
);
if
(
!
lex
<
identifier
>
())
throw_
syntax_error
(
"invalid name in @include directive"
);
Node
name
(
Node
::
identifier
,
line_number
,
lexed
);
Node
name
(
context
.
new_Node
(
Node
::
identifier
,
path
,
line_number
,
lexed
)
);
Node
args
(
parse_arguments
());
Node
args
(
parse_arguments
());
Node
call
(
Node
::
expansion
,
context
.
registry
,
line_number
,
3
);
Node
the_call
(
context
.
new_Node
(
Node
::
expansion
,
path
,
line_number
,
2
)
);
call
<<
name
<<
args
;
the_
call
<<
name
<<
args
;
return
call
;
return
the_
call
;
}
}
Node
Document
::
parse_arguments
()
Node
Document
::
parse_arguments
()
{
{
Token
name
(
lexed
);
Token
name
(
lexed
);
Node
args
(
Node
::
arguments
,
context
.
registry
,
line_number
);
Node
args
(
context
.
new_Node
(
Node
::
arguments
,
path
,
line_number
,
0
);
if
(
lex
<
exactly
<
'('
>
>
())
{
if
(
lex
<
exactly
<
'('
>
>
())
{
if
(
!
peek
<
exactly
<
')'
>
>
(
position
))
{
if
(
!
peek
<
exactly
<
')'
>
>
(
position
))
{
args
<<
parse_argument
();
Node
arg
(
parse_argument
());
args
.
content
.
children
->
back
().
eval_me
=
true
;
arg
.
should_eval
()
=
true
;
args
<<
arg
;
while
(
lex
<
exactly
<
','
>
>
())
{
while
(
lex
<
exactly
<
','
>
>
())
{
args
<<
parse_argument
();
Node
arg
(
parse_argument
());
args
.
content
.
children
->
back
().
eval_me
=
true
;
arg
.
should_eval
()
=
true
;
args
<<
arg
;
}
}
}
}
if
(
!
lex
<
exactly
<
')'
>
>
())
syntax_error
(
"improperly terminated argument list for "
+
name
.
to_string
());
if
(
!
lex
<
exactly
<
')'
>
>
())
throw_
syntax_error
(
"improperly terminated argument list for "
+
name
.
to_string
());
}
}
return
args
;
return
args
;
}
}
...
@@ -179,10 +172,10 @@ namespace Sass {
...
@@ -179,10 +172,10 @@ namespace Sass {
{
{
if
(
peek
<
sequence
<
variable
,
spaces_and_comments
,
exactly
<
':'
>
>
>
())
{
if
(
peek
<
sequence
<
variable
,
spaces_and_comments
,
exactly
<
':'
>
>
>
())
{
lex
<
variable
>
();
lex
<
variable
>
();
Node
var
(
Node
::
variable
,
line_number
,
lexed
);
Node
var
(
context
.
new_Node
(
Node
::
variable
,
path
,
line_number
,
lexed
)
);
lex
<
exactly
<
':'
>
>
();
lex
<
exactly
<
':'
>
>
();
Node
val
(
parse_space_list
());
Node
val
(
parse_space_list
());
Node
assn
(
Node
::
assignment
,
context
.
registry
,
line_number
,
2
);
Node
assn
(
context
.
new_Node
(
Node
::
assignment
,
path
,
line_number
,
2
)
);
assn
<<
var
<<
val
;
assn
<<
var
<<
val
;
return
assn
;
return
assn
;
}
}
...
@@ -194,10 +187,10 @@ namespace Sass {
...
@@ -194,10 +187,10 @@ namespace Sass {
Node
Document
::
parse_assignment
()
Node
Document
::
parse_assignment
()
{
{
lex
<
variable
>
();
lex
<
variable
>
();
Node
var
(
Node
::
variable
,
line_number
,
lexed
);
Node
var
(
context
.
new_Node
(
Node
::
variable
,
path
,
line_number
,
lexed
)
);
if
(
!
lex
<
exactly
<
':'
>
>
())
syntax_error
(
"expected ':' after "
+
lexed
.
to_string
()
+
" in assignment statement"
);
if
(
!
lex
<
exactly
<
':'
>
>
())
throw_
syntax_error
(
"expected ':' after "
+
lexed
.
to_string
()
+
" in assignment statement"
);
Node
val
(
parse_list
());
Node
val
(
parse_list
());
Node
assn
(
Node
::
assignment
,
context
.
registry
,
line_number
,
2
);
Node
assn
(
context
.
new_Node
(
Node
::
assignment
,
path
,
line_number
,
2
)
);
assn
<<
var
<<
val
;
assn
<<
var
<<
val
;
return
assn
;
return
assn
;
}
}
...
@@ -205,10 +198,10 @@ namespace Sass {
...
@@ -205,10 +198,10 @@ namespace Sass {
Node
Document
::
parse_propset
()
Node
Document
::
parse_propset
()
{
{
lex
<
identifier
>
();
lex
<
identifier
>
();
Node
property_segment
(
Node
::
identifier
,
line_number
,
lexed
);
Node
property_segment
(
context
.
new_Node
(
Node
::
identifier
,
path
,
line_number
,
lexed
)
);
lex
<
exactly
<
':'
>
>
();
lex
<
exactly
<
':'
>
>
();
lex
<
exactly
<
'{'
>
>
();
lex
<
exactly
<
'{'
>
>
();
Node
block
(
Node
::
block
,
context
.
registry
,
line_number
,
1
);
Node
block
(
context
.
new_Node
(
Node
::
block
,
path
,
line_number
,
1
)
);
while
(
!
lex
<
exactly
<
'}'
>
>
())
{
while
(
!
lex
<
exactly
<
'}'
>
>
())
{
if
(
peek
<
sequence
<
identifier
,
optional_spaces
,
exactly
<
':'
>
,
optional_spaces
,
exactly
<
'{'
>
>
>
(
position
))
{
if
(
peek
<
sequence
<
identifier
,
optional_spaces
,
exactly
<
':'
>
,
optional_spaces
,
exactly
<
'{'
>
>
>
(
position
))
{
block
<<
parse_propset
();
block
<<
parse_propset
();
...
@@ -218,8 +211,8 @@ namespace Sass {
...
@@ -218,8 +211,8 @@ namespace Sass {
lex
<
exactly
<
';'
>
>
();
lex
<
exactly
<
';'
>
>
();
}
}
}
}
if
(
block
.
size
()
==
0
)
syntax_error
(
"namespaced property cannot be empty"
);
if
(
block
.
empty
())
throw_
syntax_error
(
"namespaced property cannot be empty"
);
Node
propset
(
Node
::
propset
,
context
.
registry
,
line_number
,
2
);
Node
propset
(
context
.
new_Node
(
Node
::
propset
,
path
,
line_number
,
2
);
propset
<<
property_segment
;
propset
<<
property_segment
;
propset
<<
block
;
propset
<<
block
;
return
propset
;
return
propset
;
...
@@ -227,26 +220,19 @@ namespace Sass {
...
@@ -227,26 +220,19 @@ namespace Sass {
Node
Document
::
parse_ruleset
(
bool
definition
)
Node
Document
::
parse_ruleset
(
bool
definition
)
{
{
Node
ruleset
(
Node
::
ruleset
,
context
.
registry
,
line_number
,
2
);
Node
ruleset
(
context
.
new_Node
(
Node
::
ruleset
,
path
,
line_number
,
2
)
);
ruleset
<<
parse_selector_group
();
ruleset
<<
parse_selector_group
();
// if (ruleset[0].type == Node::selector) cerr << "ruleset starts with selector" << endl;
if
(
!
peek
<
exactly
<
'{'
>
>
())
throw_syntax_error
(
"expected a '{' after the selector"
);
// if (ruleset[0].type == Node::selector_group) cerr << "ruleset starts with selector_group" << endl;
if
(
!
peek
<
exactly
<
'{'
>
>
())
syntax_error
(
"expected a '{' after the selector"
);
ruleset
<<
parse_block
(
definition
);
ruleset
<<
parse_block
(
definition
);
return
ruleset
;
return
ruleset
;
}
}
Node
Document
::
parse_selector_group
()
Node
Document
::
parse_selector_group
()
{
{
// Node group(Node::selector_group, line_number, 1);
// group << parse_selector();
// while (lex< exactly<','> >()) group << parse_selector();
// return group;
Node
sel1
(
parse_selector
());
Node
sel1
(
parse_selector
());
if
(
!
peek
<
exactly
<
','
>
>
())
return
sel1
;
if
(
!
peek
<
exactly
<
','
>
>
())
return
sel1
;
Node
group
(
Node
::
selector_group
,
context
.
registry
,
line_number
,
2
);
Node
group
(
context
.
new_Node
(
Node
::
selector_group
,
path
,
line_number
,
2
)
);
group
<<
sel1
;
group
<<
sel1
;
while
(
lex
<
exactly
<
','
>
>
())
group
<<
parse_selector
();
while
(
lex
<
exactly
<
','
>
>
())
group
<<
parse_selector
();
return
group
;
return
group
;
...
@@ -254,40 +240,16 @@ namespace Sass {
...
@@ -254,40 +240,16 @@ namespace Sass {
Node
Document
::
parse_selector
()
Node
Document
::
parse_selector
()
{
{
// Node selector(Node::selector, line_number, 1);
// if (lex< exactly<'+'> >() ||
// lex< exactly<'~'> >() ||
// lex< exactly<'>'> >()) {
// selector << Node(Node::selector_combinator, line_number, lexed);
// }
// Node s(parse_simple_selector_sequence());
// if (s.has_backref) selector.has_backref = true;
// selector << s;
// while (lex< exactly<'+'> >() ||
// lex< exactly<'~'> >() ||
// lex< exactly<'>'> >() ||
// lex< ancestor_of >() /*||
// s.terminal_backref && lex< no_spaces >()*/) {
// selector << Node(Node::selector_combinator, line_number, lexed);
// s = parse_simple_selector_sequence();
// if (s.has_backref) selector.has_backref = true;
// selector << s;
// }
// return selector;
Node
seq1
(
parse_simple_selector_sequence
());
Node
seq1
(
parse_simple_selector_sequence
());
if
(
peek
<
exactly
<
','
>
>
()
||
if
(
peek
<
exactly
<
','
>
>
()
||
peek
<
exactly
<
')'
>
>
()
||
peek
<
exactly
<
')'
>
>
()
||
peek
<
exactly
<
'{'
>
>
())
return
seq1
;
peek
<
exactly
<
'{'
>
>
())
return
seq1
;
Node
selector
(
Node
::
selector
,
context
.
registry
,
line_number
,
2
);
Node
selector
(
context
.
new_Node
(
Node
::
selector
,
path
,
line_number
,
2
));
if
(
seq1
.
has_backref
)
selector
.
has_backref
=
true
;
selector
<<
seq1
;
selector
<<
seq1
;
while
(
!
peek
<
exactly
<
'{'
>
>
()
&&
!
peek
<
exactly
<
','
>
>
())
{
while
(
!
peek
<
exactly
<
'{'
>
>
()
&&
!
peek
<
exactly
<
','
>
>
())
{
Node
seq
(
parse_simple_selector_sequence
());
selector
<<
parse_simple_selector_sequence
();
if
(
seq
.
has_backref
)
selector
.
has_backref
=
true
;
selector
<<
seq
;
}
}
return
selector
;
return
selector
;
}
}
...
@@ -298,34 +260,30 @@ namespace Sass {
...
@@ -298,34 +260,30 @@ namespace Sass {
if
(
lex
<
exactly
<
'+'
>
>
()
||
if
(
lex
<
exactly
<
'+'
>
>
()
||
lex
<
exactly
<
'~'
>
>
()
||
lex
<
exactly
<
'~'
>
>
()
||
lex
<
exactly
<
'>'
>
>
())
lex
<
exactly
<
'>'
>
>
())
{
return
Node
(
Node
::
selector_combinator
,
line_number
,
lexed
);
}
{
return
context
.
new_Node
(
Node
::
selector_combinator
,
path
,
line_number
,
lexed
);
}
// check for backref or type selector, which are only allowed at the front
// check for backref or type selector, which are only allowed at the front
Node
simp1
;
Node
simp1
;
bool
saw_backref
=
false
;
if
(
lex
<
exactly
<
'&'
>
>
())
{
if
(
lex
<
exactly
<
'&'
>
>
())
{
simp1
=
Node
(
Node
::
backref
,
line_number
,
lexed
);
simp1
=
context
.
new_Node
(
Node
::
backref
,
path
,
line_number
,
lexed
);
simp1
.
has_backref
=
true
;
saw_backref
=
true
;
}
}
else
if
(
lex
<
alternatives
<
type_selector
,
universal
>
>
())
{
else
if
(
lex
<
alternatives
<
type_selector
,
universal
>
>
())
{
simp1
=
Node
(
Node
::
simple_selector
,
line_number
,
lexed
);
simp1
=
context
.
new_Node
(
Node
::
simple_selector
,
path
,
line_number
,
lexed
);
}
}
else
{
else
{
simp1
=
parse_simple_selector
();
simp1
=
parse_simple_selector
();
}
}
// now we have one simple/atomic selector -- see if th
ere are more
// now we have one simple/atomic selector -- see if th
at's all
if
(
peek
<
spaces
>
()
||
peek
<
exactly
<
'>'
>
>
()
||
if
(
peek
<
spaces
>
()
||
peek
<
exactly
<
'>'
>
>
()
||
peek
<
exactly
<
'+'
>
>
()
||
peek
<
exactly
<
'~'
>
>
()
||
peek
<
exactly
<
'+'
>
>
()
||
peek
<
exactly
<
'~'
>
>
()
||
peek
<
exactly
<
','
>
>
()
||
peek
<
exactly
<
')'
>
>
()
||
peek
<
exactly
<
','
>
>
()
||
peek
<
exactly
<
')'
>
>
()
||
peek
<
exactly
<
'{'
>
>
())
peek
<
exactly
<
'{'
>
>
())
{
return
simp1
;
}
{
return
simp1
;
}
//
now we know
we have a sequence of simple selectors
//
otherwise,
we have a sequence of simple selectors
Node
seq
(
Node
::
simple_selector_sequence
,
context
.
registry
,
line_number
,
2
);
Node
seq
(
context
.
new_Node
(
Node
::
simple_selector_sequence
,
path
,
line_number
,
2
)
);
seq
<<
simp1
;
seq
<<
simp1
;
seq
.
has_backref
=
saw_backref
;
while
(
!
peek
<
spaces
>
(
position
)
&&
while
(
!
peek
<
spaces
>
(
position
)
&&
!
(
peek
<
exactly
<
'+'
>
>
(
position
)
||
!
(
peek
<
exactly
<
'+'
>
>
(
position
)
||
...
@@ -337,46 +295,19 @@ namespace Sass {
...
@@ -337,46 +295,19 @@ namespace Sass {
seq
<<
parse_simple_selector
();
seq
<<
parse_simple_selector
();
}
}
return
seq
;
return
seq
;
//
// Node seq(Node::simple_selector_sequence, line_number, 1);
// if (lex< alternatives < type_selector, universal > >()) {
// seq << Node(Node::simple_selector, line_number, lexed);
// }
// else if (lex< exactly<'&'> >()) {
// seq << Node(Node::backref, line_number, lexed);
// seq.has_backref = true;
// // if (peek< sequence< no_spaces, alternatives< type_selector, universal > > >(position)) {
// // seq.terminal_backref = true;
// // return seq;
// // }
// }
// else {
// seq << parse_simple_selector();
// }
// while (!peek< spaces >(position) &&
// !(peek < exactly<'+'> >(position) ||
// peek < exactly<'~'> >(position) ||
// peek < exactly<'>'> >(position) ||
// peek < exactly<','> >(position) ||
// peek < exactly<')'> >(position) ||
// peek < exactly<'{'> >(position))) {
// seq << parse_simple_selector();
// }
// return seq;
}
}
Node
Document
::
parse_selector_combinator
()
Node
Document
::
parse_selector_combinator
()
{
{
lex
<
exactly
<
'+'
>
>
()
||
lex
<
exactly
<
'~'
>
>
()
||
lex
<
exactly
<
'+'
>
>
()
||
lex
<
exactly
<
'~'
>
>
()
||
lex
<
exactly
<
'>'
>
>
()
||
lex
<
ancestor_of
>
();
lex
<
exactly
<
'>'
>
>
()
||
lex
<
ancestor_of
>
();
return
Node
(
Node
::
selector_combinator
,
line_number
,
lexed
);
return
context
.
new_Node
(
Node
::
selector_combinator
,
path
,
line_number
,
lexed
);
}
}
Node
Document
::
parse_simple_selector
()
Node
Document
::
parse_simple_selector
()
{
{
if
(
lex
<
id_name
>
()
||
lex
<
class_name
>
())
{
if
(
lex
<
id_name
>
()
||
lex
<
class_name
>
())
{
return
Node
(
Node
::
simple_selector
,
line_number
,
lexed
);
return
context
.
new_Node
(
Node
::
simple_selector
,
path
,
line_number
,
lexed
);
}
}
else
if
(
peek
<
exactly
<
':'
>
>
(
position
))
{
else
if
(
peek
<
exactly
<
':'
>
>
(
position
))
{
return
parse_pseudo
();
return
parse_pseudo
();
...
@@ -384,76 +315,81 @@ namespace Sass {
...
@@ -384,76 +315,81 @@ namespace Sass {
else
if
(
peek
<
exactly
<
'['
>
>
(
position
))
{
else
if
(
peek
<
exactly
<
'['
>
>
(
position
))
{
return
parse_attribute_selector
();
return
parse_attribute_selector
();
}
}
syntax_error
(
"invalid selector after "
+
lexed
.
to_string
());
else
{
// unreached statement
throw_syntax_error
(
"invalid selector after "
+
lexed
.
to_string
());
return
Node
(
Node
::
none
);}
}
// unreachable statement
return
Node
();
}
Node
Document
::
parse_pseudo
()
{
Node
Document
::
parse_pseudo
()
{
if
(
lex
<
pseudo_not
>
())
{
if
(
lex
<
pseudo_not
>
())
{
Node
ps_not
(
Node
::
pseudo_negation
,
context
.
registry
,
line_number
,
2
);
Node
ps_not
(
context
.
new_Node
(
Node
::
pseudo_negation
,
path
,
line_number
,
2
)
);
ps_not
<<
Node
(
Node
::
value
,
line_number
,
lexed
);
ps_not
<<
context
.
new_Node
(
Node
::
value
,
path
,
line_number
,
lexed
);
ps_not
<<
parse_selector_group
();
ps_not
<<
parse_selector_group
();
lex
<
exactly
<
')'
>
>
();
lex
<
exactly
<
')'
>
>
();
return
ps_not
;
return
ps_not
;
}
}
else
if
(
lex
<
sequence
<
pseudo_prefix
,
functional
>
>
())
{
else
if
(
lex
<
sequence
<
pseudo_prefix
,
functional
>
>
())
{
Node
pseudo
(
Node
::
functional_pseudo
,
context
.
registry
,
line_number
,
2
);
Node
pseudo
(
context
.
new_Node
(
Node
::
functional_pseudo
,
path
,
line_number
,
2
)
);
Token
name
(
lexed
);
Token
name
(
lexed
);
pseudo
<<
Node
(
Node
::
value
,
line_number
,
name
);
pseudo
<<
context
.
new_Node
(
Node
::
value
,
path
,
line_number
,
name
);
if
(
lex
<
alternatives
<
even
,
odd
>
>
())
{
if
(
lex
<
alternatives
<
even
,
odd
>
>
())
{
pseudo
<<
Node
(
Node
::
value
,
line_number
,
lexed
);
pseudo
<<
context
.
new_Node
(
Node
::
value
,
path
,
line_number
,
lexed
);
}
}
else
if
(
peek
<
binomial
>
(
position
))
{
else
if
(
peek
<
binomial
>
(
position
))
{
lex
<
coefficient
>
();
lex
<
coefficient
>
();
pseudo
<<
Node
(
Node
::
value
,
line_number
,
lexed
);
pseudo
<<
context
.
new_Node
(
Node
::
value
,
path
,
line_number
,
lexed
);
lex
<
exactly
<
'n'
>
>
();
lex
<
exactly
<
'n'
>
>
();
pseudo
<<
Node
(
Node
::
value
,
line_number
,
lexed
);
pseudo
<<
context
.
new_Node
(
Node
::
value
,
path
,
line_number
,
lexed
);
lex
<
sign
>
();
lex
<
sign
>
();
pseudo
<<
Node
(
Node
::
value
,
line_number
,
lexed
);
pseudo
<<
context
.
new_Node
(
Node
::
value
,
path
,
line_number
,
lexed
);
lex
<
digits
>
();
lex
<
digits
>
();
pseudo
<<
Node
(
Node
::
value
,
line_number
,
lexed
);
pseudo
<<
context
.
new_Node
(
Node
::
value
,
path
,
line_number
,
lexed
);
}
}
else
if
(
lex
<
sequence
<
optional
<
sign
>
,
else
if
(
lex
<
sequence
<
optional
<
sign
>
,
optional
<
digits
>
,
optional
<
digits
>
,
exactly
<
'n'
>
>
>
())
{
exactly
<
'n'
>
>
>
())
{
pseudo
<<
Node
(
Node
::
value
,
line_number
,
lexed
);
pseudo
<<
context
.
new_Node
(
Node
::
value
,
path
,
line_number
,
lexed
);
}
}
else
if
(
lex
<
sequence
<
optional
<
sign
>
,
digits
>
>
())
{
else
if
(
lex
<
sequence
<
optional
<
sign
>
,
digits
>
>
())
{
pseudo
<<
Node
(
Node
::
value
,
line_number
,
lexed
);
pseudo
<<
context
.
new_Node
(
Node
::
value
,
path
,
line_number
,
lexed
);
}
}
else
if
(
lex
<
string_constant
>
())
{
else
if
(
lex
<
string_constant
>
())
{
pseudo
<<
Node
(
Node
::
string_constant
,
line_number
,
lexed
);
pseudo
<<
context
.
new_Node
(
Node
::
string_constant
,
path
,
line_number
,
lexed
);
}
}
else
{
else
{
syntax_error
(
"invalid argument to "
+
name
.
to_string
()
+
"...)"
);
syntax_error
(
"invalid argument to "
+
name
.
to_string
()
+
"...)"
);
}
}
if
(
!
lex
<
exactly
<
')'
>
>
())
syntax_error
(
"unterminated argument to "
+
name
.
to_string
()
+
"...)"
);
if
(
!
lex
<
exactly
<
')'
>
>
())
throw_
syntax_error
(
"unterminated argument to "
+
name
.
to_string
()
+
"...)"
);
return
pseudo
;
return
pseudo
;
}
}
else
if
(
lex
<
sequence
<
pseudo_prefix
,
identifier
>
>
())
{
else
if
(
lex
<
sequence
<
pseudo_prefix
,
identifier
>
>
())
{
return
Node
(
Node
::
pseudo
,
line_number
,
lexed
);
return
context
.
new_Node
(
Node
::
pseudo
,
path
,
line_number
,
lexed
);
}
}
syntax_error
(
"unrecognized pseudo-class or pseudo-element"
);
else
{
// unreached statement
throw_syntax_error
(
"unrecognized pseudo-class or pseudo-element"
);
return
Node
(
Node
::
none
);
}
// unreachable statement
return
Node
();
}
}
Node
Document
::
parse_attribute_selector
()
Node
Document
::
parse_attribute_selector
()
{
{
Node
attr_sel
(
Node
::
attribute_selector
,
context
.
registry
,
line_number
,
3
);
Node
attr_sel
(
context
.
new_Node
(
Node
::
attribute_selector
,
path
,
line_number
,
3
)
);
lex
<
exactly
<
'['
>
>
();
lex
<
exactly
<
'['
>
>
();
if
(
!
lex
<
type_selector
>
())
syntax_error
(
"invalid attribute name in attribute selector"
);
if
(
!
lex
<
type_selector
>
())
throw_
syntax_error
(
"invalid attribute name in attribute selector"
);
Token
name
(
lexed
);
Token
name
(
lexed
);
attr_sel
<<
Node
(
Node
::
value
,
line_number
,
name
);
attr_sel
<<
context
.
new_Node
(
Node
::
value
,
path
,
line_number
,
name
);
if
(
lex
<
exactly
<
']'
>
>
())
return
attr_sel
;
if
(
lex
<
exactly
<
']'
>
>
())
return
attr_sel
;
if
(
!
lex
<
alternatives
<
exact_match
,
class_match
,
dash_match
,
if
(
!
lex
<
alternatives
<
exact_match
,
class_match
,
dash_match
,
prefix_match
,
suffix_match
,
substring_match
>
>
())
{
prefix_match
,
suffix_match
,
substring_match
>
>
())
{
syntax_error
(
"invalid operator in attribute selector for "
+
name
.
to_string
());
throw_
syntax_error
(
"invalid operator in attribute selector for "
+
name
.
to_string
());
}
}
attr_sel
<<
Node
(
Node
::
value
,
line_number
,
lexed
);
attr_sel
<<
context
.
new_Node
(
Node
::
value
,
path
,
line_number
,
lexed
);
if
(
!
lex
<
string_constant
>
())
syntax_error
(
"expected a quoted string constant in attribute selector for "
+
name
.
to_string
());
if
(
!
lex
<
string_constant
>
())
throw_
syntax_error
(
"expected a quoted string constant in attribute selector for "
+
name
.
to_string
());
attr_sel
<<
Node
(
Node
::
value
,
line_number
,
lexed
);
attr_sel
<<
context
.
new_Node
(
Node
::
value
,
path
,
line_number
,
lexed
);
if
(
!
lex
<
exactly
<
']'
>
>
())
syntax_error
(
"unterminated attribute selector for "
+
name
.
to_string
());
if
(
!
lex
<
exactly
<
']'
>
>
())
throw_
syntax_error
(
"unterminated attribute selector for "
+
name
.
to_string
());
return
attr_sel
;
return
attr_sel
;
}
}
...
@@ -461,43 +397,30 @@ namespace Sass {
...
@@ -461,43 +397,30 @@ namespace Sass {
{
{
lex
<
exactly
<
'{'
>
>
();
lex
<
exactly
<
'{'
>
>
();
bool
semicolon
=
false
;
bool
semicolon
=
false
;
Node
block
(
Node
::
block
,
context
.
registry
,
line_number
,
1
);
Node
block
(
context
.
new_Node
(
Node
::
block
,
path
,
line_number
,
0
));
block
<<
Node
(
Node
::
flags
);
while
(
!
lex
<
exactly
<
'}'
>
>
())
{
while
(
!
lex
<
exactly
<
'}'
>
>
())
{
if
(
semicolon
)
{
if
(
semicolon
)
{
if
(
!
lex
<
exactly
<
';'
>
>
())
syntax_error
(
"non-terminal statement or declaration must end with ';'"
);
if
(
!
lex
<
exactly
<
';'
>
>
())
throw_
syntax_error
(
"non-terminal statement or declaration must end with ';'"
);
semicolon
=
false
;
semicolon
=
false
;
while
(
lex
<
block_comment
>
())
{
while
(
lex
<
block_comment
>
())
{
block
<<
Node
(
Node
::
comment
,
line_number
,
lexed
);
block
<<
context
.
new_Node
(
Node
::
comment
,
path
,
line_number
,
lexed
);
block
[
0
].
has_statements
=
true
;
}
}
if
(
lex
<
exactly
<
'}'
>
>
())
break
;
if
(
lex
<
exactly
<
'}'
>
>
())
break
;
}
}
if
(
lex
<
block_comment
>
())
{
if
(
lex
<
block_comment
>
())
{
block
<<
Node
(
Node
::
comment
,
line_number
,
lexed
);
block
<<
context
.
new_Node
(
Node
::
comment
,
path
,
line_number
,
lexed
);
block
[
0
].
has_statements
=
true
;
//semicolon = true;
}
}
else
if
(
peek
<
import
>
(
position
))
{
else
if
(
peek
<
import
>
(
position
))
{
if
(
definition
)
{
if
(
definition
)
{
lex
<
import
>
();
// to adjust the line number
lex
<
import
>
();
// to adjust the line number
syntax_error
(
"@import directive not allowed inside mixin definition"
);
throw_
syntax_error
(
"@import directive not allowed inside mixin definition"
);
}
}
Node
imported_tree
(
parse_import
());
Node
imported_tree
(
parse_import
());
if
(
imported_tree
.
type
==
Node
::
css_import
)
{
if
(
imported_tree
.
type
()
==
Node
::
css_import
)
{
// cerr << "css import inside block" << endl;
block
<<
imported_tree
;
block
<<
imported_tree
;
block
.
has_statements
=
true
;
}
}
else
{
else
{
for
(
size_t
i
=
0
;
i
<
imported_tree
.
size
();
++
i
)
{
for
(
size_t
i
=
0
,
S
=
imported_tree
.
size
();
i
<
S
;
++
i
)
{
if
(
imported_tree
[
i
].
type
==
Node
::
comment
||
imported_tree
[
i
].
type
==
Node
::
rule
)
{
block
[
0
].
has_statements
=
true
;
}
else
if
(
imported_tree
[
i
].
type
==
Node
::
ruleset
)
{
block
[
0
].
has_blocks
=
true
;
}
block
<<
imported_tree
[
i
];
block
<<
imported_tree
[
i
];
}
}
semicolon
=
true
;
semicolon
=
true
;
...
@@ -505,7 +428,6 @@ namespace Sass {
...
@@ -505,7 +428,6 @@ namespace Sass {
}
}
else
if
(
peek
<
include
>
(
position
))
{
else
if
(
peek
<
include
>
(
position
))
{
block
<<
parse_mixin_call
();
block
<<
parse_mixin_call
();
block
[
0
].
has_expansions
=
true
;
semicolon
=
true
;
semicolon
=
true
;
}
}
else
if
(
lex
<
variable
>
())
{
else
if
(
lex
<
variable
>
())
{
...
@@ -514,15 +436,12 @@ namespace Sass {
...
@@ -514,15 +436,12 @@ namespace Sass {
}
}
else
if
(
peek
<
sequence
<
identifier
,
optional_spaces
,
exactly
<
':'
>
,
optional_spaces
,
exactly
<
'{'
>
>
>
(
position
))
{
else
if
(
peek
<
sequence
<
identifier
,
optional_spaces
,
exactly
<
':'
>
,
optional_spaces
,
exactly
<
'{'
>
>
>
(
position
))
{
block
<<
parse_propset
();
block
<<
parse_propset
();
block
[
0
].
has_statements
=
true
;
}
}
else
if
(
lookahead_for_selector
(
position
))
{
else
if
(
lookahead_for_selector
(
position
))
{
block
<<
parse_ruleset
(
definition
);
block
<<
parse_ruleset
(
definition
);
block
[
0
].
has_blocks
=
true
;
}
}
else
if
(
peek
<
exactly
<
'+'
>
>
())
{
else
if
(
peek
<
exactly
<
'+'
>
>
())
{
block
<<
parse_mixin_call
();
block
<<
parse_mixin_call
();
block
[
0
].
has_expansions
=
true
;
semicolon
=
true
;
semicolon
=
true
;
}
}
else
if
(
!
peek
<
exactly
<
';'
>
>
())
{
else
if
(
!
peek
<
exactly
<
';'
>
>
())
{
...
@@ -530,10 +449,11 @@ namespace Sass {
...
@@ -530,10 +449,11 @@ namespace Sass {
// check for lbrace; if it's there, we have a namespace property with a value
// check for lbrace; if it's there, we have a namespace property with a value
if
(
peek
<
exactly
<
'{'
>
>
())
{
if
(
peek
<
exactly
<
'{'
>
>
())
{
Node
inner
(
parse_block
());
Node
inner
(
parse_block
());
Node
propset
(
Node
::
propset
,
context
.
registry
,
line_number
,
2
);
Node
propset
(
context
.
new_Node
(
Node
::
propset
,
path
,
line_number
,
2
)
);
propset
<<
rule
[
0
];
propset
<<
rule
[
0
];
rule
[
0
]
=
Node
(
Node
::
property
,
line_number
,
Token
::
make
());
rule
[
0
]
=
context
.
new_Node
(
Node
::
property
,
path
,
line_number
,
Token
::
make
());
inner
[
0
]
=
rule
;
// inner[0] = rule;
inner
.
push_front
(
rule
);
propset
<<
inner
;
propset
<<
inner
;
block
<<
propset
;
block
<<
propset
;
// cerr << block[block.size()-1][0].content.token.to_string() << endl;
// cerr << block[block.size()-1][0].content.token.to_string() << endl;
...
@@ -542,25 +462,23 @@ namespace Sass {
...
@@ -542,25 +462,23 @@ namespace Sass {
block
<<
rule
;
block
<<
rule
;
semicolon
=
true
;
semicolon
=
true
;
}
}
block
[
0
].
has_statements
=
true
;
}
}
else
lex
<
exactly
<
';'
>
>
();
else
lex
<
exactly
<
';'
>
>
();
while
(
lex
<
block_comment
>
())
{
while
(
lex
<
block_comment
>
())
{
block
<<
Node
(
Node
::
comment
,
line_number
,
lexed
);
block
<<
context
.
new_Node
(
Node
::
comment
,
path
,
line_number
,
lexed
);
block
[
0
].
has_statements
=
true
;
}
}
}
}
return
block
;
return
block
;
}
}
Node
Document
::
parse_rule
()
{
Node
Document
::
parse_rule
()
{
Node
rule
(
Node
::
rule
,
context
.
registry
,
line_number
,
2
);
Node
rule
(
context
.
new_Node
(
Node
::
rule
,
path
,
line_number
,
2
)
);
if
(
!
lex
<
sequence
<
optional
<
exactly
<
'*'
>
>
,
identifier
>
>
())
{
if
(
!
lex
<
sequence
<
optional
<
exactly
<
'*'
>
>
,
identifier
>
>
())
{
lex
<
spaces_and_comments
>
();
// get the line number right
lex
<
spaces_and_comments
>
();
// get the line number right
syntax_error
(
"invalid property name"
);
throw_
syntax_error
(
"invalid property name"
);
}
}
rule
<<
Node
(
Node
::
property
,
line_number
,
lexed
);
rule
<<
context
.
new_Node
(
Node
::
property
,
path
,
line_number
,
lexed
);
if
(
!
lex
<
exactly
<
':'
>
>
())
syntax_error
(
"property
\"
"
+
lexed
.
to_string
()
+
"
\"
must be followed by a ':'"
);
if
(
!
lex
<
exactly
<
':'
>
>
())
throw_
syntax_error
(
"property
\"
"
+
lexed
.
to_string
()
+
"
\"
must be followed by a ':'"
);
rule
<<
parse_list
();
rule
<<
parse_list
();
return
rule
;
return
rule
;
}
}
...
@@ -576,20 +494,20 @@ namespace Sass {
...
@@ -576,20 +494,20 @@ namespace Sass {
peek
<
exactly
<
'}'
>
>
(
position
)
||
peek
<
exactly
<
'}'
>
>
(
position
)
||
peek
<
exactly
<
'{'
>
>
(
position
)
||
peek
<
exactly
<
'{'
>
>
(
position
)
||
peek
<
exactly
<
')'
>
>
(
position
))
peek
<
exactly
<
')'
>
>
(
position
))
{
return
Node
(
Node
::
nil
,
context
.
registry
,
line_number
);
}
{
return
context
.
new_Node
(
Node
::
nil
,
path
,
line_number
,
0
);
}
Node
list1
(
parse_space_list
());
Node
list1
(
parse_space_list
());
// if it's a singleton, return it directly; don't wrap it
// if it's a singleton, return it directly; don't wrap it
if
(
!
peek
<
exactly
<
','
>
>
(
position
))
return
list1
;
if
(
!
peek
<
exactly
<
','
>
>
(
position
))
return
list1
;
Node
comma_list
(
Node
::
comma_list
,
context
.
registry
,
line_number
,
2
);
Node
comma_list
(
context
.
new_Node
(
Node
::
comma_list
,
path
,
line_number
,
2
)
);
comma_list
<<
list1
;
comma_list
<<
list1
;
comma_list
.
eval_me
|=
list1
.
eval_me
;
comma_list
.
should_eval
()
|=
list1
.
should_eval
()
;
while
(
lex
<
exactly
<
','
>
>
())
while
(
lex
<
exactly
<
','
>
>
())
{
{
Node
list
(
parse_space_list
());
Node
list
(
parse_space_list
());
comma_list
<<
list
;
comma_list
<<
list
;
comma_list
.
eval_me
|=
list
.
eval_me
;
comma_list
.
should_eval
()
|=
list
.
should_eval
()
;
}
}
return
comma_list
;
return
comma_list
;
...
@@ -606,9 +524,9 @@ namespace Sass {
...
@@ -606,9 +524,9 @@ namespace Sass {
peek
<
exactly
<
','
>
>
(
position
))
peek
<
exactly
<
','
>
>
(
position
))
{
return
disj1
;
}
{
return
disj1
;
}
Node
space_list
(
Node
::
space_list
,
context
.
registry
,
line_number
,
2
);
Node
space_list
(
context
.
new_Node
(
Node
::
space_list
,
path
,
line_number
,
2
)
);
space_list
<<
disj1
;
space_list
<<
disj1
;
space_list
.
eval_me
|=
disj1
.
eval_me
;
space_list
.
should_eval
()
|=
disj1
.
should_eval
()
;
while
(
!
(
peek
<
exactly
<
';'
>
>
(
position
)
||
while
(
!
(
peek
<
exactly
<
';'
>
>
(
position
)
||
peek
<
exactly
<
'}'
>
>
(
position
)
||
peek
<
exactly
<
'}'
>
>
(
position
)
||
...
@@ -618,7 +536,7 @@ namespace Sass {
...
@@ -618,7 +536,7 @@ namespace Sass {
{
{
Node
disj
(
parse_disjunction
());
Node
disj
(
parse_disjunction
());
space_list
<<
disj
;
space_list
<<
disj
;
space_list
.
eval_me
|=
disj
.
eval_me
;
space_list
.
should_eval
()
|=
disj
.
should_eval
()
;
}
}
return
space_list
;
return
space_list
;
...
@@ -630,10 +548,10 @@ namespace Sass {
...
@@ -630,10 +548,10 @@ namespace Sass {
// if it's a singleton, return it directly; don't wrap it
// if it's a singleton, return it directly; don't wrap it
if
(
!
peek
<
sequence
<
or_kwd
,
negate
<
identifier
>
>
>
())
return
conj1
;
if
(
!
peek
<
sequence
<
or_kwd
,
negate
<
identifier
>
>
>
())
return
conj1
;
Node
disjunction
(
Node
::
disjunction
,
context
.
registry
,
line_number
,
2
);
Node
disjunction
(
context
.
new_Node
(
Node
::
disjunction
,
path
,
line_number
,
2
)
);
disjunction
<<
conj1
;
disjunction
<<
conj1
;
while
(
lex
<
sequence
<
or_kwd
,
negate
<
identifier
>
>
>
())
disjunction
<<
parse_conjunction
();
while
(
lex
<
sequence
<
or_kwd
,
negate
<
identifier
>
>
>
())
disjunction
<<
parse_conjunction
();
disjunction
.
eval_me
=
true
;
disjunction
.
should_eval
()
=
true
;
return
disjunction
;
return
disjunction
;
}
}
...
@@ -644,10 +562,10 @@ namespace Sass {
...
@@ -644,10 +562,10 @@ namespace Sass {
// if it's a singleton, return it directly; don't wrap it
// if it's a singleton, return it directly; don't wrap it
if
(
!
peek
<
sequence
<
and_kwd
,
negate
<
identifier
>
>
>
())
return
rel1
;
if
(
!
peek
<
sequence
<
and_kwd
,
negate
<
identifier
>
>
>
())
return
rel1
;
Node
conjunction
(
Node
::
conjunction
,
context
.
registry
,
line_number
,
2
);
Node
conjunction
(
context
.
new_Node
(
Node
::
conjunction
,
path
,
line_number
,
2
)
);
conjunction
<<
rel1
;
conjunction
<<
rel1
;
while
(
lex
<
sequence
<
and_kwd
,
negate
<
identifier
>
>
>
())
conjunction
<<
parse_relation
();
while
(
lex
<
sequence
<
and_kwd
,
negate
<
identifier
>
>
>
())
conjunction
<<
parse_relation
();
conjunction
.
eval_me
=
true
;
conjunction
.
should_eval
()
=
true
;
return
conjunction
;
return
conjunction
;
}
}
...
@@ -663,22 +581,22 @@ namespace Sass {
...
@@ -663,22 +581,22 @@ namespace Sass {
peek
<
lte_op
>
(
position
)))
peek
<
lte_op
>
(
position
)))
{
return
expr1
;
}
{
return
expr1
;
}
Node
relation
(
Node
::
relation
,
context
.
registry
,
line_number
,
3
);
Node
relation
(
context
.
new_Node
(
Node
::
relation
,
path
,
line_number
,
3
)
);
expr1
.
eval_me
=
true
;
expr1
.
should_eval
()
=
true
;
relation
<<
expr1
;
relation
<<
expr1
;
if
(
lex
<
eq_op
>
())
relation
<<
Node
(
Node
::
eq
,
line_number
,
lexed
);
if
(
lex
<
eq_op
>
())
relation
<<
context
.
new_Node
(
Node
::
eq
,
path
,
line_number
,
lexed
);
else
if
(
lex
<
neq_op
>
())
relation
<<
Node
(
Node
::
neq
,
line_number
,
lexed
);
else
if
(
lex
<
neq_op
>
())
relation
<<
context
.
new_Node
(
Node
::
neq
,
path
,
line_number
,
lexed
);
else
if
(
lex
<
gte_op
>
())
relation
<<
Node
(
Node
::
gte
,
line_number
,
lexed
);
else
if
(
lex
<
gte_op
>
())
relation
<<
context
.
new_Node
(
Node
::
gte
,
path
,
line_number
,
lexed
);
else
if
(
lex
<
lte_op
>
())
relation
<<
Node
(
Node
::
lte
,
line_number
,
lexed
);
else
if
(
lex
<
lte_op
>
())
relation
<<
context
.
new_Node
(
Node
::
lte
,
path
,
line_number
,
lexed
);
else
if
(
lex
<
gt_op
>
())
relation
<<
Node
(
Node
::
gt
,
line_number
,
lexed
);
else
if
(
lex
<
gt_op
>
())
relation
<<
context
.
new_Node
(
Node
::
gt
,
path
,
line_number
,
lexed
);
else
if
(
lex
<
lt_op
>
())
relation
<<
Node
(
Node
::
lt
,
line_number
,
lexed
);
else
if
(
lex
<
lt_op
>
())
relation
<<
context
.
new_Node
(
Node
::
lt
,
path
,
line_number
,
lexed
);
Node
expr2
(
parse_expression
());
Node
expr2
(
parse_expression
());
expr2
.
eval_me
=
true
;
expr2
.
should_eval
()
=
true
;
relation
<<
expr2
;
relation
<<
expr2
;
relation
.
eval_me
=
true
;
relation
.
should_eval
()
=
true
;
return
relation
;
return
relation
;
}
}
...
@@ -690,22 +608,22 @@ namespace Sass {
...
@@ -690,22 +608,22 @@ namespace Sass {
peek
<
sequence
<
negate
<
number
>
,
exactly
<
'-'
>
>
>
(
position
)))
peek
<
sequence
<
negate
<
number
>
,
exactly
<
'-'
>
>
>
(
position
)))
{
return
term1
;
}
{
return
term1
;
}
Node
expression
(
Node
::
expression
,
context
.
registry
,
line_number
,
3
);
Node
expression
(
context
.
new_Node
(
Node
::
expression
,
path
,
line_number
,
3
)
);
term1
.
eval_me
=
true
;
term1
.
should_eval
()
=
true
;
expression
<<
term1
;
expression
<<
term1
;
while
(
lex
<
exactly
<
'+'
>
>
()
||
lex
<
sequence
<
negate
<
number
>
,
exactly
<
'-'
>
>
>
())
{
while
(
lex
<
exactly
<
'+'
>
>
()
||
lex
<
sequence
<
negate
<
number
>
,
exactly
<
'-'
>
>
>
())
{
if
(
lexed
.
begin
[
0
]
==
'+'
)
{
if
(
lexed
.
begin
[
0
]
==
'+'
)
{
expression
<<
Node
(
Node
::
add
,
line_number
,
lexed
);
expression
<<
context
.
new_Node
(
Node
::
add
,
path
,
line_number
,
lexed
);
}
}
else
{
else
{
expression
<<
Node
(
Node
::
sub
,
line_number
,
lexed
);
expression
<<
context
.
new_Node
(
Node
::
sub
,
path
,
line_number
,
lexed
);
}
}
Node
term
(
parse_term
());
Node
term
(
parse_term
());
term
.
eval_me
=
true
;
term
.
should_eval
()
=
true
;
expression
<<
term
;
expression
<<
term
;
}
}
expression
.
eval_me
=
true
;
expression
.
should_eval
()
=
true
;
return
expression
;
return
expression
;
}
}
...
@@ -718,20 +636,20 @@ namespace Sass {
...
@@ -718,20 +636,20 @@ namespace Sass {
peek
<
exactly
<
'/'
>
>
(
position
)))
peek
<
exactly
<
'/'
>
>
(
position
)))
{
return
fact1
;
}
{
return
fact1
;
}
Node
term
(
Node
::
term
,
context
.
registry
,
line_number
,
3
);
Node
term
(
context
.
new_Node
(
Node
::
term
,
path
,
line_number
,
3
)
);
term
<<
fact1
;
term
<<
fact1
;
if
(
fact1
.
eval_me
)
term
.
eval_me
=
true
;
if
(
fact1
.
should_eval
())
term
.
should_eval
()
=
true
;
while
(
lex
<
exactly
<
'*'
>
>
()
||
lex
<
exactly
<
'/'
>
>
())
{
while
(
lex
<
exactly
<
'*'
>
>
()
||
lex
<
exactly
<
'/'
>
>
())
{
if
(
lexed
.
begin
[
0
]
==
'*'
)
{
if
(
lexed
.
begin
[
0
]
==
'*'
)
{
term
<<
Node
(
Node
::
mul
,
line_number
,
lexed
);
term
<<
context
.
new_Node
(
Node
::
mul
,
path
,
line_number
,
lexed
);
term
.
eval_me
=
true
;
term
.
should_eval
()
=
true
;
}
}
else
{
else
{
term
<<
Node
(
Node
::
div
,
line_number
,
lexed
);
term
<<
context
.
new_Node
(
Node
::
div
,
path
,
line_number
,
lexed
);
}
}
Node
fact
(
parse_factor
());
Node
fact
(
parse_factor
());
if
(
fact
.
eval_me
)
term
.
eval_me
=
true
;
term
.
should_eval
()
|=
fact
.
should_eval
()
;
term
<<
fact
;
term
<<
fact
;
}
}
...
@@ -742,23 +660,23 @@ namespace Sass {
...
@@ -742,23 +660,23 @@ namespace Sass {
{
{
if
(
lex
<
exactly
<
'('
>
>
())
{
if
(
lex
<
exactly
<
'('
>
>
())
{
Node
value
(
parse_comma_list
());
Node
value
(
parse_comma_list
());
value
.
eval_me
=
true
;
value
.
should_eval
()
=
true
;
if
(
value
.
type
==
Node
::
comma_list
||
value
.
type
==
Node
::
space_list
)
{
if
(
value
.
type
()
==
Node
::
comma_list
||
value
.
type
()
==
Node
::
space_list
)
{
value
[
0
].
eval_me
=
true
;
value
[
0
].
should_eval
()
=
true
;
}
}
if
(
!
lex
<
exactly
<
')'
>
>
())
syntax_error
(
"unclosed parenthesis"
);
if
(
!
lex
<
exactly
<
')'
>
>
())
throw_
syntax_error
(
"unclosed parenthesis"
);
return
value
;
return
value
;
}
}
else
if
(
lex
<
sequence
<
exactly
<
'+'
>
,
negate
<
number
>
>
>
())
{
else
if
(
lex
<
sequence
<
exactly
<
'+'
>
,
negate
<
number
>
>
>
())
{
Node
plus
(
Node
::
unary_plus
,
context
.
registry
,
line_number
,
1
);
Node
plus
(
context
.
new_Node
(
Node
::
unary_plus
,
path
,
line_number
,
1
)
);
plus
<<
parse_factor
();
plus
<<
parse_factor
();
plus
.
eval_me
=
true
;
plus
.
should_eval
()
=
true
;
return
plus
;
return
plus
;
}
}
else
if
(
lex
<
sequence
<
exactly
<
'-'
>
,
negate
<
number
>
>
>
())
{
else
if
(
lex
<
sequence
<
exactly
<
'-'
>
,
negate
<
number
>
>
>
())
{
Node
minus
(
Node
::
unary_minus
,
context
.
registry
,
line_number
,
1
);
Node
minus
(
context
.
new_Node
(
Node
::
unary_minus
,
path
,
line_number
,
1
)
);
minus
<<
parse_factor
();
minus
<<
parse_factor
();
minus
.
eval_me
=
true
;
minus
.
should_eval
()
=
true
;
return
minus
;
return
minus
;
}
}
else
{
else
{
...
@@ -772,10 +690,10 @@ namespace Sass {
...
@@ -772,10 +690,10 @@ namespace Sass {
{
{
const
char
*
value
=
position
;
const
char
*
value
=
position
;
const
char
*
rparen
=
find_first
<
exactly
<
')'
>
>
(
position
);
const
char
*
rparen
=
find_first
<
exactly
<
')'
>
>
(
position
);
if
(
!
rparen
)
syntax_error
(
"URI is missing ')'"
);
if
(
!
rparen
)
throw_
syntax_error
(
"URI is missing ')'"
);
Token
contents
(
Token
::
make
(
value
,
rparen
));
Token
contents
(
Token
::
make
(
value
,
rparen
));
// lex< string_constant >();
// lex< string_constant >();
Node
result
(
Node
::
uri
,
line_number
,
contents
);
Node
result
(
context
.
new_Node
(
Node
::
uri
,
path
,
line_number
,
contents
)
);
position
=
rparen
;
position
=
rparen
;
lex
<
exactly
<
')'
>
>
();
lex
<
exactly
<
')'
>
>
();
return
result
;
return
result
;
...
@@ -783,10 +701,8 @@ namespace Sass {
...
@@ -783,10 +701,8 @@ namespace Sass {
if
(
lex
<
value_schema
>
())
if
(
lex
<
value_schema
>
())
{
{
// cerr << "parsing value schema: " << lexed.to_string() << endl;
// cerr << "parsing value schema: " << lexed.to_string() << endl;
return
Document
::
make_from_token
(
context
,
lexed
,
path
,
line_number
).
parse_value_schema
();
Document
schema_doc
(
path
,
line_number
,
lexed
,
context
);
return
schema_doc
.
parse_value_schema
();
}
}
if
(
lex
<
sequence
<
true_kwd
,
negate
<
identifier
>
>
>
())
if
(
lex
<
sequence
<
true_kwd
,
negate
<
identifier
>
>
>
())
...
@@ -833,7 +749,7 @@ namespace Sass {
...
@@ -833,7 +749,7 @@ namespace Sass {
if
(
lex
<
variable
>
())
if
(
lex
<
variable
>
())
{
{
Node
var
(
Node
::
variable
,
line_number
,
lexed
);
Node
var
(
Node
::
variable
,
line_number
,
lexed
);
var
.
eval_me
=
true
;
var
.
should_eval
()
=
true
;
return
var
;
return
var
;
}
}
...
@@ -856,7 +772,7 @@ namespace Sass {
...
@@ -856,7 +772,7 @@ namespace Sass {
return
Node
(
Node
::
string_constant
,
line_number
,
str
);
return
Node
(
Node
::
string_constant
,
line_number
,
str
);
}
}
Node
schema
(
Node
::
string_schema
,
context
.
registry
,
line_number
,
1
);
Node
schema
(
Node
::
string_schema
,
path
,
line_number
,
1
);
while
(
i
<
str
.
end
)
{
while
(
i
<
str
.
end
)
{
p
=
find_first_in_interval
<
sequence
<
negate
<
exactly
<
'\\'
>
>
,
exactly
<
hash_lbrace
>
>
>
(
i
,
str
.
end
);
p
=
find_first_in_interval
<
sequence
<
negate
<
exactly
<
'\\'
>
>
,
exactly
<
hash_lbrace
>
>
>
(
i
,
str
.
end
);
if
(
p
)
{
if
(
p
)
{
...
@@ -870,7 +786,7 @@ namespace Sass {
...
@@ -870,7 +786,7 @@ namespace Sass {
// cerr << '[' << Token::make(p, j-1).to_string() << ']' << endl;
// cerr << '[' << Token::make(p, j-1).to_string() << ']' << endl;
Document
interp_doc
(
path
,
line_number
,
Token
::
make
(
p
,
j
-
1
),
context
);
Document
interp_doc
(
path
,
line_number
,
Token
::
make
(
p
,
j
-
1
),
context
);
Node
interp_node
(
interp_doc
.
parse_list
());
Node
interp_node
(
interp_doc
.
parse_list
());
interp_node
.
eval_me
=
true
;
interp_node
.
should_eval
()
=
true
;
schema
<<
interp_node
;
schema
<<
interp_node
;
i
=
j
;
i
=
j
;
}
}
...
@@ -889,7 +805,7 @@ namespace Sass {
...
@@ -889,7 +805,7 @@ namespace Sass {
Node
Document
::
parse_value_schema
()
Node
Document
::
parse_value_schema
()
{
{
Node
schema
(
Node
::
value_schema
,
context
.
registry
,
line_number
,
1
);
Node
schema
(
Node
::
value_schema
,
path
,
line_number
,
1
);
while
(
position
<
end
)
{
while
(
position
<
end
)
{
if
(
lex
<
interpolant
>
())
{
if
(
lex
<
interpolant
>
())
{
...
@@ -923,7 +839,7 @@ namespace Sass {
...
@@ -923,7 +839,7 @@ namespace Sass {
syntax_error
(
"error parsing interpolated value"
);
syntax_error
(
"error parsing interpolated value"
);
}
}
}
}
schema
.
eval_me
=
true
;
schema
.
should_eval
()
=
true
;
return
schema
;
return
schema
;
}
}
...
@@ -932,9 +848,9 @@ namespace Sass {
...
@@ -932,9 +848,9 @@ namespace Sass {
lex
<
identifier
>
();
lex
<
identifier
>
();
Node
name
(
Node
::
identifier
,
line_number
,
lexed
);
Node
name
(
Node
::
identifier
,
line_number
,
lexed
);
Node
args
(
parse_arguments
());
Node
args
(
parse_arguments
());
Node
call
(
Node
::
function_call
,
context
.
registry
,
line_number
,
2
);
Node
call
(
Node
::
function_call
,
path
,
line_number
,
2
);
call
<<
name
<<
args
;
call
<<
name
<<
args
;
call
.
eval_me
=
true
;
call
.
should_eval
()
=
true
;
return
call
;
return
call
;
}
}
...
...
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