From 6f360d2155dc429af078b73044a845d3b644d0a4 Mon Sep 17 00:00:00 2001 From: Marcel Greter Date: Mon, 9 Mar 2015 02:50:46 +0100 Subject: [PATCH] Implement number prefix parsing (/[\+\-]+/) Fixes https://github.com/sass/libsass/issues/535 --- parser.cpp | 20 ++++++++++++++++++++ parser.hpp | 1 + prelexer.cpp | 12 ++++++++++++ prelexer.hpp | 2 ++ 4 files changed, 35 insertions(+) diff --git a/parser.cpp b/parser.cpp index 1156985e24..04213b9f53 100644 --- a/parser.cpp +++ b/parser.cpp @@ -941,6 +941,22 @@ namespace Sass { } } + // parse +/- and return false if negative + bool Parser::parse_number_prefix() + { + bool positive = true; + while(true) { + if (lex < block_comment >()) continue; + if (lex < number_prefix >()) continue; + if (lex < exactly < '-' > >()) { + positive = !positive; + continue; + } + break; + } + return positive; + } + Expression* Parser::parse_map() { To_String to_string(&ctx); @@ -1203,6 +1219,10 @@ namespace Sass { else if (lex< sequence< not_op, spaces_and_comments > >()) { return new (ctx.mem) Unary_Expression(pstate, Unary_Expression::NOT, parse_factor()); } + else if (peek < sequence < one_plus < alternatives < spaces_and_comments, exactly<'-'>, exactly<'+'> > >, number > >()) { + if (parse_number_prefix()) return parse_value(); // prefix is positive + return new (ctx.mem) Unary_Expression(pstate, Unary_Expression::MINUS, parse_value()); + } else { return parse_value(); } diff --git a/parser.hpp b/parser.hpp index 757b7b855f..8f6a061adf 100644 --- a/parser.hpp +++ b/parser.hpp @@ -234,6 +234,7 @@ namespace Sass { Simple_Selector* parse_pseudo_selector(); Attribute_Selector* parse_attribute_selector(); Block* parse_block(); + bool parse_number_prefix(); Declaration* parse_declaration(); Expression* parse_map_value(); Expression* parse_map(); diff --git a/prelexer.cpp b/prelexer.cpp index 189987e308..d1f6065348 100644 --- a/prelexer.cpp +++ b/prelexer.cpp @@ -147,6 +147,18 @@ namespace Sass { return sequence< exactly<'-'>, exactly<'-'>, identifier >(src); } + // Match number prefix ([\+\-]+) + const char* number_prefix(const char* src) { + return alternatives < + exactly < '+' >, + sequence < + exactly < '-' >, + optional_spaces_and_comments, + exactly< '-' > + > + >(src); + } + // Match interpolant schemas const char* identifier_schema(const char* src) { // follows this pattern: (x*ix*)+ ... well, not quite diff --git a/prelexer.hpp b/prelexer.hpp index ba18b131c4..0a2324f49e 100644 --- a/prelexer.hpp +++ b/prelexer.hpp @@ -396,6 +396,8 @@ namespace Sass { const char* quoted_string(const char* src); // Match interpolants. const char* interpolant(const char* src); + // Match number prefix ([\+\-]+) + const char* number_prefix(const char* src); // Whitespace handling. const char* optional_spaces(const char* src);