aboutsummaryrefslogtreecommitdiff
path: root/libbuild2
diff options
context:
space:
mode:
Diffstat (limited to 'libbuild2')
-rw-r--r--libbuild2/parser.cxx44
-rw-r--r--libbuild2/parser.hxx32
2 files changed, 55 insertions, 21 deletions
diff --git a/libbuild2/parser.cxx b/libbuild2/parser.cxx
index fbf3bda..2cb51c6 100644
--- a/libbuild2/parser.cxx
+++ b/libbuild2/parser.cxx
@@ -212,6 +212,17 @@ namespace build2
};
void parser::
+ reset ()
+ {
+ pre_parse_ = false;
+ attributes_.clear ();
+ default_target_ = nullptr;
+ peeked_ = false;
+ replay_ = replay::stop;
+ replay_data_.clear ();
+ }
+
+ void parser::
parse_buildfile (istream& is, const path_name& in, scope& root, scope& base)
{
lexer l (is, in);
@@ -223,12 +234,13 @@ namespace build2
{
path_ = &l.name ();
lexer_ = &l;
+
root_ = &root;
scope_ = &base;
- pbase_ = scope_->src_path_;
target_ = nullptr;
prerequisite_ = nullptr;
- default_target_ = nullptr;
+
+ pbase_ = scope_->src_path_;
enter_buildfile (*path_); // Needs scope_.
@@ -249,11 +261,14 @@ namespace build2
{
path_ = &l.name ();
lexer_ = &l;
+
+ root_ = nullptr;
scope_ = &s;
- pbase_ = scope_->src_path_; // Normally NULL.
target_ = nullptr;
prerequisite_ = nullptr;
+ pbase_ = scope_->src_path_; // Normally NULL.
+
token t;
type tt;
parse_variable (t, tt, var, kind);
@@ -268,11 +283,14 @@ namespace build2
{
path_ = &l.name ();
lexer_ = &l;
+
+ root_ = nullptr;
scope_ = &s;
- pbase_ = b;
target_ = nullptr;
prerequisite_ = nullptr;
+ pbase_ = b;
+
token t;
type tt;
value rhs (parse_variable_value (t, tt));
@@ -1968,9 +1986,9 @@ namespace build2
if (val.type != nullptr)
untypify (val);
- export_value_ = move (val).as<names> ();
+ export_value = move (val).as<names> ();
- if (export_value_.empty ())
+ if (export_value.empty ())
fail (l) << "empty value in export";
next_after_newline (t, tt);
@@ -3675,7 +3693,7 @@ namespace build2
bool has (tt == type::lsbrace);
if (!pre_parse_)
- attributes_.push (attributes {has, l, {}});
+ attributes_.push_back (attributes {has, l, {}});
if (!has)
return make_pair (false, l);
@@ -3727,7 +3745,7 @@ namespace build2
}
if (!pre_parse_)
- attributes_.top ().ats.emplace_back (move (n), move (v));
+ attributes_.back ().ats.emplace_back (move (n), move (v));
if (tt == type::comma)
next (t, tt);
@@ -5592,18 +5610,20 @@ namespace build2
buildspec parser::
parse_buildspec (istream& is, const path_name& in)
{
- path_ = &in;
-
// We do "effective escaping" and only for ['"\$(] (basically what's
// necessary inside a double-quoted literal plus the single quote).
//
+ path_ = &in;
lexer l (is, *path_, 1 /* line */, "\'\"\\$(");
lexer_ = &l;
- scope_ = root_ = &ctx.global_scope.rw ();
- pbase_ = &work; // Use current working directory.
+
+ root_ = &ctx.global_scope.rw ();
+ scope_ = root_;
target_ = nullptr;
prerequisite_ = nullptr;
+ pbase_ = &work; // Use current working directory.
+
// Turn on the buildspec mode/pairs recognition with '@' as the pair
// separator (e.g., src_root/@out_root/exe{foo bar}).
//
diff --git a/libbuild2/parser.hxx b/libbuild2/parser.hxx
index ba707da..6d78ce1 100644
--- a/libbuild2/parser.hxx
+++ b/libbuild2/parser.hxx
@@ -4,8 +4,6 @@
#ifndef LIBBUILD2_PARSER_HXX
#define LIBBUILD2_PARSER_HXX
-#include <stack>
-
#include <libbuild2/types.hxx>
#include <libbuild2/forward.hxx>
#include <libbuild2/utility.hxx>
@@ -60,9 +58,22 @@ namespace build2
parse_export_stub (istream& is, const path_name& name, scope& r, scope& b)
{
parse_buildfile (is, name, r, b);
- return move (export_value_);
+ return move (export_value);
}
+ // The above functions may be called again on the same parser instance
+ // after a reset.
+ //
+ void
+ reset ();
+
+ // Ad hoc parsing results for some cases.
+ //
+ // Note that these are not touched by reset().
+ //
+ public:
+ names export_value;
+
// Recursive descent parser.
//
protected:
@@ -246,13 +257,13 @@ namespace build2
attributes_pop ()
{
assert (!pre_parse_);
- attributes r (move (attributes_.top ()));
- attributes_.pop ();
+ attributes r (move (attributes_.back ()));
+ attributes_.pop_back ();
return r;
}
attributes&
- attributes_top () {return attributes_.top ();}
+ attributes_top () {return attributes_.back ();}
// Source a stream optionnaly entering it as a buildfile and performing
// the default target processing.
@@ -703,6 +714,10 @@ namespace build2
protected:
const fail_mark fail;
+ // Parser state.
+ //
+ // NOTE: remember to update reset() if adding anything here.
+ //
protected:
context& ctx;
stage stage_;
@@ -719,10 +734,9 @@ namespace build2
const dir_path* pbase_ = nullptr; // Current pattern base directory.
- std::stack<attributes> attributes_;
+ small_vector<attributes, 2> attributes_;
- target* default_target_;
- names export_value_;
+ target* default_target_ = nullptr;
replay_token peek_;
bool peeked_ = false;