aboutsummaryrefslogtreecommitdiff
path: root/build/lexer.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2015-03-06 09:15:40 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2015-03-06 09:15:40 +0200
commit897a0e4fdf9ca90ee8d236a38e138a8ae6bc3627 (patch)
treed4c00de32d028823906d342fcd984faee8d977ff /build/lexer.cxx
parent9ef25ab2f9da89ab48ecce3fe1b8cbb0bc5f1e09 (diff)
Add support for lexing and parsing name pairs
We will need it for the buildspec and also if/when we support map variable types.
Diffstat (limited to 'build/lexer.cxx')
-rw-r--r--build/lexer.cxx77
1 files changed, 60 insertions, 17 deletions
diff --git a/build/lexer.cxx b/build/lexer.cxx
index 5f394fc..9683567 100644
--- a/build/lexer.cxx
+++ b/build/lexer.cxx
@@ -11,6 +11,12 @@ namespace build
token lexer::
next ()
{
+ if (mode_ != next_mode_)
+ {
+ prev_mode_ = mode_;
+ mode_ = next_mode_;
+ }
+
bool sep (skip_spaces ());
xchar c (get ());
@@ -27,8 +33,8 @@ namespace build
{
// Restore the normal mode at the end of the line.
//
- if (mode_ == mode::value)
- mode_ = mode::normal;
+ if (mode_ == lexer_mode::value || mode_ == lexer_mode::pairs)
+ mode_ = next_mode_ = lexer_mode::normal;
return token (token_type::newline, sep, ln, cn);
}
@@ -42,7 +48,10 @@ namespace build
}
case '$':
{
- mode_ = mode::variable; // The next name is lexed in the var mode.
+ // The following name is lexed in the variable mode.
+ //
+ next_mode_ = lexer_mode::variable;
+
return token (token_type::dollar, sep, ln, cn);
}
case '(':
@@ -56,9 +65,9 @@ namespace build
}
// The following characters are not treated as special in the
- // value mode.
+ // value or pairs mode.
//
- if (mode_ != mode::value)
+ if (mode_ != lexer_mode::value && mode_ != lexer_mode::pairs)
{
// NOTE: remember to update name() if adding new punctuations.
//
@@ -68,22 +77,39 @@ namespace build
{
return token (token_type::colon, sep, ln, cn);
}
- case '=':
- {
- mode_ = mode::value;
- return token (token_type::equal, sep, ln, cn);
- }
case '+':
{
if (get () != '=')
fail (c) << "expected = after +";
- mode_ = mode::value;
+ next_mode_ = lexer_mode::value;
return token (token_type::plus_equal, sep, ln, cn);
}
}
}
+ // The following characters are not treated as special in the
+ // value mode.
+ //
+ if (mode_ != lexer_mode::value)
+ {
+ // NOTE: remember to update name() if adding new punctuations.
+ //
+ switch (c)
+ {
+ case '=':
+ {
+ // Unless we are already in the pairs mode, switch to the
+ // value mode.
+ //
+ if (next_mode_ != lexer_mode::pairs)
+ next_mode_ = lexer_mode::value;
+
+ return token (token_type::equal, sep, ln, cn);
+ }
+ }
+ }
+
// Otherwise it is a name.
//
return name (c, sep);
@@ -101,14 +127,13 @@ namespace build
bool done (false);
// The following characters are not treated as special in the
- // value mode.
+ // value or pairs mode.
//
- if (mode_ != mode::value)
+ if (mode_ != lexer_mode::value && mode_ != lexer_mode::pairs)
{
switch (c)
{
case ':':
- case '=':
case '+':
{
done = true;
@@ -120,10 +145,28 @@ namespace build
break;
}
+ // The following characters are not treated as special in the
+ // value mode.
+ //
+ if (mode_ != lexer_mode::value)
+ {
+ switch (c)
+ {
+ case '=':
+ {
+ done = true;
+ break;
+ }
+ }
+
+ if (done)
+ break;
+ }
+
// While these extra characters are treated as the name end in
// the variable mode.
//
- if (mode_ == mode::variable)
+ if (mode_ == lexer_mode::variable)
{
switch (c)
{
@@ -171,8 +214,8 @@ namespace build
break;
}
- if (mode_ == mode::variable)
- mode_ = mode::normal;
+ if (mode_ == lexer_mode::variable)
+ next_mode_ = prev_mode_;
return token (lexeme, sep, ln, cn);
}