aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/parser.hxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2020-04-28 08:48:53 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2020-05-27 15:47:28 +0200
commitb808c255b6a9ddba085bf5646e7d20ec344f2e2d (patch)
tree32730291f7e6de8ef0a227905520dd66fb4ec0f3 /libbuild2/parser.hxx
parent3552356a87402727e663131994fa87f48b3cd4fb (diff)
Initial support for ad hoc recipes (still work in progress)
Diffstat (limited to 'libbuild2/parser.hxx')
-rw-r--r--libbuild2/parser.hxx43
1 files changed, 36 insertions, 7 deletions
diff --git a/libbuild2/parser.hxx b/libbuild2/parser.hxx
index c55e14f..bc01e08 100644
--- a/libbuild2/parser.hxx
+++ b/libbuild2/parser.hxx
@@ -26,7 +26,9 @@ namespace build2
explicit
parser (context& c, stage s = stage::rest)
- : fail ("error", &path_), ctx (c), stage_ (s) {}
+ : fail ("error", &path_), info ("info", &path_),
+ ctx (c),
+ stage_ (s) {}
// Issue diagnostics and throw failed in case of an error.
//
@@ -109,6 +111,11 @@ namespace build2
const target_type* = nullptr,
string = string ());
+ void
+ parse_recipe (token&, token_type&,
+ const token&,
+ small_vector<shared_ptr<adhoc_rule>, 1>&);
+
// Ad hoc target names inside < ... >.
//
struct adhoc_names_loc
@@ -246,6 +253,9 @@ namespace build2
build2::value value;
};
+ friend ostream&
+ operator<< (ostream&, const attribute&);
+
struct attributes: small_vector<attribute, 1>
{
location loc; // Start location.
@@ -479,6 +489,12 @@ namespace build2
// If qual is not empty, then its pair member should indicate the kind
// of qualification: ':' -- target, '/' -- scope.
//
+ // Note that this function is called even during pre-parse with the result
+ // unused. In this case a valid name will only be provided for variables
+ // with literal names (for example, $x, $(x)). For computed variables (for
+ // example, $($x ? X : Y)) it will be empty (along with qual, which can
+ // only be non-empty for a computed variable).
+ //
virtual lookup
lookup_variable (name&& qual, string&& name, const location&);
@@ -525,8 +541,14 @@ namespace build2
// If the current token is newline, then get the next token. Otherwise,
// fail unless the current token is eos (i.e., optional newline at the end
- // of stream). If the after argument is not \0, use it in diagnostics as
- // the token after which the newline was expectd.
+ // of stream). Use the after token in diagnostics as the token after which
+ // the newline was expected.
+ //
+ token_type
+ next_after_newline (token&, token_type&, const token& after);
+
+ // As above but the after argument is a single-character token. If it is
+ // \0, then it is ignored.
//
token_type
next_after_newline (token&, token_type&, char after = '\0');
@@ -568,10 +590,10 @@ namespace build2
}
void
- mode (lexer_mode m, char ps = '\0')
+ mode (lexer_mode m, char ps = '\0', uintptr_t d = 0)
{
if (replay_ != replay::play)
- lexer_->mode (m, ps);
+ lexer_->mode (m, ps, nullopt, d);
else
// As a sanity check, make sure the mode matches the next token. Note
// that we don't check the attributes flags or the pair separator
@@ -612,8 +634,10 @@ namespace build2
// with the lexer directly (e.g., the keyword() test). Replays also cannot
// nest. For now we don't enforce any of this.
//
- // Note also that the peeked token is not part of the replay, until it
- // is "got".
+ // Note also that the peeked token is not part of the replay until it is
+ // "got". In particular, this means that we cannot peek past the replay
+ // sequence (since we will get the peeked token as the first token of
+ // the replay).
//
void
replay_save ()
@@ -628,6 +652,8 @@ namespace build2
assert ((replay_ == replay::save && !replay_data_.empty ()) ||
(replay_ == replay::play && replay_i_ == replay_data_.size ()));
+ assert (!peeked_);
+
if (replay_ == replay::save)
replay_path_ = path_; // Save old path.
@@ -638,6 +664,8 @@ namespace build2
void
replay_stop ()
{
+ assert (!peeked_);
+
if (replay_ == replay::play)
path_ = replay_path_; // Restore old path.
@@ -726,6 +754,7 @@ namespace build2
//
protected:
const fail_mark fail;
+ const basic_mark info;
// Parser state.
//