Compare commits
No commits in common. "35996484b2eb2cce769172f10f1102ad091e86e1" and "af7f6768fd2caa17043ce746e33fea2ba0cfc862" have entirely different histories.
35996484b2
...
af7f6768fd
|
@ -5,9 +5,7 @@ DEPS ::= LITERAL*
|
||||||
BLOCK ::= obrace CMD_LST cbrace
|
BLOCK ::= obrace CMD_LST cbrace
|
||||||
CMD_LST ::= (CMD (comma CMD)* comma?)?
|
CMD_LST ::= (CMD (comma CMD)* comma?)?
|
||||||
CMD ::= LITERAL*
|
CMD ::= LITERAL*
|
||||||
LITERAL ::= ident | var | ARRAY | INDEX
|
LITERAL ::= ident | var | ARRAY
|
||||||
|
|
||||||
VAR_DECL ::= var assign (LITERAL | ARRAY | INDEX)
|
VAR_DECL ::= var assign (LITERAL | ARRAY)
|
||||||
ARRAY ::= opar LITERAL* cpar
|
ARRAY ::= opar LITERAL* cpar
|
||||||
INDEX ::=
|
|
||||||
| (var|ARRAY) osquare ident (assign ident)? csquare
|
|
||||||
|
|
|
@ -135,7 +135,7 @@ namespace sn
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string>
|
std::vector<std::string>
|
||||||
Interpreter::get_value(std::shared_ptr<Node> node) const
|
Interpreter::get_value(std::shared_ptr<Node> node)
|
||||||
{
|
{
|
||||||
if (node->type() == NODE_IDENT)
|
if (node->type() == NODE_IDENT)
|
||||||
{
|
{
|
||||||
|
@ -162,73 +162,6 @@ namespace sn
|
||||||
|
|
||||||
return values;
|
return values;
|
||||||
}
|
}
|
||||||
else if (node->type() == NODE_INDEX)
|
|
||||||
{
|
|
||||||
auto var = *node->get(0);
|
|
||||||
auto val = *node->get(1);
|
|
||||||
|
|
||||||
if (node->size() > 2)
|
|
||||||
// Extension replacement
|
|
||||||
{
|
|
||||||
auto old_values = get_value(var);
|
|
||||||
std::vector<std::string> values;
|
|
||||||
std::string src_extension = val->repr();
|
|
||||||
std::string dest_extension = (*node->get(2))->repr();
|
|
||||||
|
|
||||||
std::transform(std::begin(old_values), std::end(old_values),
|
|
||||||
std::back_inserter(values),
|
|
||||||
[src_extension, dest_extension]
|
|
||||||
(auto const& val){
|
|
||||||
auto val_p = std::filesystem::path(val);
|
|
||||||
|
|
||||||
if (val_p.has_extension()
|
|
||||||
&& val_p.extension() == src_extension)
|
|
||||||
{
|
|
||||||
return val_p.replace_extension(dest_extension);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return val_p;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return values;
|
|
||||||
}
|
|
||||||
else if (val->repr().size() > 0 && val->repr()[0] == '.')
|
|
||||||
// Extension modifier
|
|
||||||
{
|
|
||||||
auto old_values = get_value(var);
|
|
||||||
std::vector<std::string> values;
|
|
||||||
std::string extension = val->repr();
|
|
||||||
|
|
||||||
std::transform(std::begin(old_values), std::end(old_values),
|
|
||||||
std::back_inserter(values),
|
|
||||||
[extension](auto const& val){
|
|
||||||
auto val_p = std::filesystem::path(val);
|
|
||||||
return val_p.replace_extension(extension);
|
|
||||||
});
|
|
||||||
|
|
||||||
return values;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
// Index selector
|
|
||||||
{
|
|
||||||
auto values = get_value(var);
|
|
||||||
ssize_t index = std::stoi(val->repr());
|
|
||||||
|
|
||||||
if (index < 0)
|
|
||||||
{
|
|
||||||
index = values.size() + index;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index >= static_cast<ssize_t>(values.size()))
|
|
||||||
{
|
|
||||||
throw run_error {"invalid index '" + std::to_string(index) + "'"};
|
|
||||||
}
|
|
||||||
|
|
||||||
return { values[index] };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw run_error {"cannot find value for '"
|
throw run_error {"cannot find value for '"
|
||||||
+ SN_GET(NodeTypeStr, node->type(), "NODE_")
|
+ SN_GET(NodeTypeStr, node->type(), "NODE_")
|
||||||
|
@ -336,19 +269,33 @@ namespace sn
|
||||||
auto cmd = *block->get(i);
|
auto cmd = *block->get(i);
|
||||||
|
|
||||||
std::string script;
|
std::string script;
|
||||||
|
std::string sep;
|
||||||
|
|
||||||
for (size_t j=0; j<cmd->size(); j++)
|
for (size_t j=0; j<cmd->size(); j++)
|
||||||
{
|
{
|
||||||
auto c = *cmd->get(j);
|
auto c = *cmd->get(j);
|
||||||
|
|
||||||
auto values = get_value(c);
|
if (c->type() == NODE_IDENT)
|
||||||
std::string vsep = (j > 0) ? " " : "";
|
|
||||||
|
|
||||||
for (auto val: values)
|
|
||||||
{
|
{
|
||||||
script += vsep + val;
|
script += sep + c->repr();
|
||||||
vsep = " ";
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto var = *m_sym.get(c->repr());
|
||||||
|
std::string vsep;
|
||||||
|
|
||||||
|
if (j > 0)
|
||||||
|
{
|
||||||
|
vsep = " ";
|
||||||
|
}
|
||||||
|
for (auto const& v: var.values)
|
||||||
|
{
|
||||||
|
script += vsep + v;
|
||||||
|
vsep = " ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sep = " ";
|
||||||
}
|
}
|
||||||
|
|
||||||
result.push_back(script);
|
result.push_back(script);
|
||||||
|
|
|
@ -41,7 +41,7 @@ namespace sn
|
||||||
std::vector<std::string>> m_scripts;
|
std::vector<std::string>> m_scripts;
|
||||||
SymTable m_sym;
|
SymTable m_sym;
|
||||||
|
|
||||||
std::vector<std::string> get_value(std::shared_ptr<Node> node) const;
|
std::vector<std::string> get_value(std::shared_ptr<Node> node);
|
||||||
|
|
||||||
std::vector<std::filesystem::path>
|
std::vector<std::filesystem::path>
|
||||||
targets(std::filesystem::path path) const;
|
targets(std::filesystem::path path) const;
|
||||||
|
|
|
@ -9,9 +9,6 @@ namespace sn
|
||||||
m_separators.push_back('\n');
|
m_separators.push_back('\n');
|
||||||
m_separators.push_back(' ');
|
m_separators.push_back(' ');
|
||||||
|
|
||||||
add_text("[", NODE_OSQUARE);
|
|
||||||
add_text("]", NODE_CSQUARE);
|
|
||||||
|
|
||||||
add_text("(", NODE_OPAR);
|
add_text("(", NODE_OPAR);
|
||||||
add_text(")", NODE_CPAR);
|
add_text(")", NODE_CPAR);
|
||||||
add_text("=", NODE_ASSIGN);
|
add_text("=", NODE_ASSIGN);
|
||||||
|
|
|
@ -8,8 +8,7 @@
|
||||||
G(NODE_CBRACE), G(NODE_CMD), G(NODE_CMD_LST), G(NODE_COMMA), \
|
G(NODE_CBRACE), G(NODE_CMD), G(NODE_CMD_LST), G(NODE_COMMA), \
|
||||||
G(NODE_BLOCK), G(NODE_TARGET), G(NODE_DEPS), G(NODE_RULE), \
|
G(NODE_BLOCK), G(NODE_TARGET), G(NODE_DEPS), G(NODE_RULE), \
|
||||||
G(NODE_VAR), G(NODE_ASSIGN), G(NODE_VAR_DECL), G(NODE_OPAR), \
|
G(NODE_VAR), G(NODE_ASSIGN), G(NODE_VAR_DECL), G(NODE_OPAR), \
|
||||||
G(NODE_CPAR), G(NODE_ARRAY), G(NODE_INDEX), G(NODE_OSQUARE), \
|
G(NODE_CPAR), G(NODE_ARRAY)
|
||||||
G(NODE_CSQUARE)
|
|
||||||
|
|
||||||
namespace sn
|
namespace sn
|
||||||
{
|
{
|
||||||
|
|
|
@ -180,12 +180,6 @@ namespace sn
|
||||||
|
|
||||||
std::shared_ptr<Node> Parser::parse_literal()
|
std::shared_ptr<Node> Parser::parse_literal()
|
||||||
{
|
{
|
||||||
if (type_is(NODE_VAR)
|
|
||||||
&& type_is(NODE_OSQUARE, 1))
|
|
||||||
{
|
|
||||||
return parse_index(*consume(NODE_VAR));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type_is(NODE_IDENT)
|
if (type_is(NODE_IDENT)
|
||||||
|| type_is(NODE_VAR))
|
|| type_is(NODE_VAR))
|
||||||
{
|
{
|
||||||
|
@ -194,14 +188,7 @@ namespace sn
|
||||||
|
|
||||||
if (type_is(NODE_OPAR))
|
if (type_is(NODE_OPAR))
|
||||||
{
|
{
|
||||||
auto array = parse_array();
|
return parse_array();
|
||||||
|
|
||||||
if (type_is(NODE_OSQUARE))
|
|
||||||
{
|
|
||||||
return parse_index(array);
|
|
||||||
}
|
|
||||||
|
|
||||||
return array;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
throw syntax_error {"unknown token '"
|
throw syntax_error {"unknown token '"
|
||||||
|
@ -219,16 +206,7 @@ namespace sn
|
||||||
|
|
||||||
if (type_is(NODE_OPAR))
|
if (type_is(NODE_OPAR))
|
||||||
{
|
{
|
||||||
auto array = parse_array();
|
node->add_child(parse_array());
|
||||||
|
|
||||||
if (type_is(NODE_OSQUARE))
|
|
||||||
{
|
|
||||||
node->add_child(parse_index(array));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
node->add_child(array);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -253,24 +231,4 @@ namespace sn
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<Node> Parser::parse_index(std::shared_ptr<Node> lhs)
|
|
||||||
{
|
|
||||||
auto node = std::make_shared<Node>(NODE_INDEX);
|
|
||||||
|
|
||||||
node->add_child(lhs);
|
|
||||||
|
|
||||||
consume(NODE_OSQUARE);
|
|
||||||
node->add_child(*consume(NODE_IDENT));
|
|
||||||
|
|
||||||
if (type_is(NODE_ASSIGN))
|
|
||||||
{
|
|
||||||
consume();
|
|
||||||
node->add_child(*consume(NODE_IDENT));
|
|
||||||
}
|
|
||||||
|
|
||||||
consume(NODE_CSQUARE);
|
|
||||||
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,6 @@ namespace sn
|
||||||
std::shared_ptr<Node> parse_literal();
|
std::shared_ptr<Node> parse_literal();
|
||||||
std::shared_ptr<Node> parse_var_decl();
|
std::shared_ptr<Node> parse_var_decl();
|
||||||
std::shared_ptr<Node> parse_array();
|
std::shared_ptr<Node> parse_array();
|
||||||
std::shared_ptr<Node> parse_index(std::shared_ptr<Node> lhs);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -84,13 +84,6 @@ public:
|
||||||
!= std::end(vec));
|
!= std::end(vec));
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_not_contains(std::string const& str, std::vector<std::string> vec)
|
|
||||||
{
|
|
||||||
INFO("'" << str << "' found");
|
|
||||||
REQUIRE(std::find(std::begin(vec), std::end(vec), str)
|
|
||||||
== std::end(vec));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -175,147 +168,3 @@ TEST_CASE_METHOD(InterpreterTest, "Interpreter_array_var")
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_METHOD(InterpreterTest, "Interpreter_array_index")
|
|
||||||
{
|
|
||||||
SECTION("get second: ok")
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << "$X = (a b c)" << std::endl;
|
|
||||||
ss << "d -> $X[1] {" << std::endl;
|
|
||||||
ss << "executed" << std::endl;
|
|
||||||
ss << "}" << std::endl;
|
|
||||||
|
|
||||||
auto res = TEST_RUN(ss.str(), std::filesystem::path("b"));
|
|
||||||
test_contains("executed", res);
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION("get second: not ok")
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << "$X = (a b c)" << std::endl;
|
|
||||||
ss << "d -> $X[1] {" << std::endl;
|
|
||||||
ss << "executed" << std::endl;
|
|
||||||
ss << "}" << std::endl;
|
|
||||||
|
|
||||||
auto res = TEST_RUN(ss.str(), std::filesystem::path("a"));
|
|
||||||
test_not_contains("executed", res);
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION("get last: ok")
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << "$X = (a b c)" << std::endl;
|
|
||||||
ss << "d -> $X[-1] {" << std::endl;
|
|
||||||
ss << "executed" << std::endl;
|
|
||||||
ss << "}" << std::endl;
|
|
||||||
|
|
||||||
auto res = TEST_RUN(ss.str(), std::filesystem::path("c"));
|
|
||||||
test_contains("executed", res);
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION("get last: not ok")
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << "$X = (a b c)" << std::endl;
|
|
||||||
ss << "d -> $X[-1] {" << std::endl;
|
|
||||||
ss << "executed" << std::endl;
|
|
||||||
ss << "}" << std::endl;
|
|
||||||
|
|
||||||
auto res = TEST_RUN(ss.str(), std::filesystem::path("b"));
|
|
||||||
test_not_contains("executed", res);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE_METHOD(InterpreterTest, "Interpreter_array_literal_index")
|
|
||||||
{
|
|
||||||
SECTION("get second: ok")
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << "$X = (a b c)[1]" << std::endl;
|
|
||||||
ss << "d -> $X {" << std::endl;
|
|
||||||
ss << "executed" << std::endl;
|
|
||||||
ss << "}" << std::endl;
|
|
||||||
|
|
||||||
auto res = TEST_RUN(ss.str(), std::filesystem::path("b"));
|
|
||||||
test_contains("executed", res);
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION("get second: not ok")
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << "$X = (a b c)[1]" << std::endl;
|
|
||||||
ss << "d -> $X {" << std::endl;
|
|
||||||
ss << "executed" << std::endl;
|
|
||||||
ss << "}" << std::endl;
|
|
||||||
|
|
||||||
auto res = TEST_RUN(ss.str(), std::filesystem::path("a"));
|
|
||||||
test_not_contains("executed", res);
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION("get last: ok")
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << "$X = (a b c)[-1]" << std::endl;
|
|
||||||
ss << "d -> $X {" << std::endl;
|
|
||||||
ss << "executed" << std::endl;
|
|
||||||
ss << "}" << std::endl;
|
|
||||||
|
|
||||||
auto res = TEST_RUN(ss.str(), std::filesystem::path("c"));
|
|
||||||
test_contains("executed", res);
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION("get last: not ok")
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << "$X = (a b c)[-1]" << std::endl;
|
|
||||||
ss << "d -> $X {" << std::endl;
|
|
||||||
ss << "executed" << std::endl;
|
|
||||||
ss << "}" << std::endl;
|
|
||||||
|
|
||||||
auto res = TEST_RUN(ss.str(), std::filesystem::path("b"));
|
|
||||||
test_not_contains("executed", res);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE_METHOD(InterpreterTest, "Interpreter_select_ext")
|
|
||||||
{
|
|
||||||
SECTION("on var")
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << "$Y = g.h" << std::endl;
|
|
||||||
ss << "d -> a {" << std::endl;
|
|
||||||
ss << "$Y $Y[.hpp] $Y[.cpp]" << std::endl;
|
|
||||||
ss << "}" << std::endl;
|
|
||||||
|
|
||||||
auto res = TEST_RUN(ss.str(), std::filesystem::path("a"));
|
|
||||||
test_contains("g.h g.hpp g.cpp", res);
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION("on array")
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << "$Y = (x.c y.c z.d)" << std::endl;
|
|
||||||
ss << "d -> a {" << std::endl;
|
|
||||||
ss << "$Y[.cpp]" << std::endl;
|
|
||||||
ss << "}" << std::endl;
|
|
||||||
|
|
||||||
auto res = TEST_RUN(ss.str(), std::filesystem::path("a"));
|
|
||||||
test_contains("x.cpp y.cpp z.cpp", res);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE_METHOD(InterpreterTest, "Interpreter_replace_ext")
|
|
||||||
{
|
|
||||||
SECTION("on array")
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << "$Y = (x.c y.c z.d w t.h)" << std::endl;
|
|
||||||
ss << "d -> a {" << std::endl;
|
|
||||||
ss << "$Y[.c=.h]" << std::endl;
|
|
||||||
ss << "}" << std::endl;
|
|
||||||
|
|
||||||
auto res = TEST_RUN(ss.str(), std::filesystem::path("a"));
|
|
||||||
test_contains("x.h y.h z.d w t.h", res);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -54,11 +54,9 @@ TEST_CASE_METHOD(LexerTest, "Lexer_vars")
|
||||||
|
|
||||||
TEST_CASE_METHOD(LexerTest, "Lexer_arrays")
|
TEST_CASE_METHOD(LexerTest, "Lexer_arrays")
|
||||||
{
|
{
|
||||||
m_lexer.scan(" ()[] ");
|
m_lexer.scan(" () ");
|
||||||
|
|
||||||
test_next("OPAR");
|
test_next("OPAR");
|
||||||
test_next("CPAR");
|
test_next("CPAR");
|
||||||
test_next("OSQUARE");
|
|
||||||
test_next("CSQUARE");
|
|
||||||
test_end();
|
test_end();
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,89 +130,3 @@ TEST_CASE_METHOD(ParserTest, "Parser_array")
|
||||||
")))",
|
")))",
|
||||||
ss.str());
|
ss.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_METHOD(ParserTest, "Parser_array_index")
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << "$BIM = hello.cpp" << std::endl;
|
|
||||||
ss << "$BAM = (world.hpp world.cpp)" << std::endl;
|
|
||||||
ss << " $BIM -> (hello.cpp world.cpp) {" << std::endl;
|
|
||||||
ss << " g++ $BIM[4] -o hello.elf, " << std::endl;
|
|
||||||
ss << " ls " << std::endl;
|
|
||||||
ss << " }" << std::endl;
|
|
||||||
|
|
||||||
test_parse("DOC("
|
|
||||||
"VAR_DECL(VAR[BIM],IDENT[hello.cpp]),"
|
|
||||||
"VAR_DECL(VAR[BAM],ARRAY(IDENT[world.hpp],IDENT[world.cpp])),"
|
|
||||||
"RULE("
|
|
||||||
"TARGET("
|
|
||||||
"VAR[BIM]"
|
|
||||||
"),DEPS("
|
|
||||||
"ARRAY(IDENT[hello.cpp],IDENT[world.cpp])"
|
|
||||||
"),BLOCK("
|
|
||||||
"CMD("
|
|
||||||
"IDENT[g++],INDEX(VAR[BIM],IDENT[4]),IDENT[-o],IDENT[hello.elf]"
|
|
||||||
"),CMD("
|
|
||||||
"IDENT[ls]"
|
|
||||||
")"
|
|
||||||
")))",
|
|
||||||
ss.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE_METHOD(ParserTest, "Parser_array_index_literal")
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << "$BIM = hello.cpp" << std::endl;
|
|
||||||
ss << "$BAM = (world.hpp world.cpp)[14]" << std::endl;
|
|
||||||
ss << " $BIM -> (hello.cpp world.cpp) {" << std::endl;
|
|
||||||
ss << " g++ $BIM[4] -o hello.elf, " << std::endl;
|
|
||||||
ss << " ls " << std::endl;
|
|
||||||
ss << " }" << std::endl;
|
|
||||||
|
|
||||||
test_parse("DOC("
|
|
||||||
"VAR_DECL(VAR[BIM],IDENT[hello.cpp]),"
|
|
||||||
"VAR_DECL(VAR[BAM],"
|
|
||||||
"INDEX(ARRAY(IDENT[world.hpp],IDENT[world.cpp]),IDENT[14])),"
|
|
||||||
"RULE("
|
|
||||||
"TARGET("
|
|
||||||
"VAR[BIM]"
|
|
||||||
"),DEPS("
|
|
||||||
"ARRAY(IDENT[hello.cpp],IDENT[world.cpp])"
|
|
||||||
"),BLOCK("
|
|
||||||
"CMD("
|
|
||||||
"IDENT[g++],INDEX(VAR[BIM],IDENT[4]),IDENT[-o],IDENT[hello.elf]"
|
|
||||||
"),CMD("
|
|
||||||
"IDENT[ls]"
|
|
||||||
")"
|
|
||||||
")))",
|
|
||||||
ss.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE_METHOD(ParserTest, "Parser_replace_ext_index")
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << "$BIM = hello.cpp" << std::endl;
|
|
||||||
ss << "$BAM = (world.hpp world.cpp)[14]" << std::endl;
|
|
||||||
ss << " $BIM -> (hello.cpp world.cpp) {" << std::endl;
|
|
||||||
ss << " g++ $BIM[.c=.o] -o hello.elf, " << std::endl;
|
|
||||||
ss << " ls " << std::endl;
|
|
||||||
ss << " }" << std::endl;
|
|
||||||
|
|
||||||
test_parse("DOC("
|
|
||||||
"VAR_DECL(VAR[BIM],IDENT[hello.cpp]),"
|
|
||||||
"VAR_DECL(VAR[BAM],"
|
|
||||||
"INDEX(ARRAY(IDENT[world.hpp],IDENT[world.cpp]),IDENT[14])),"
|
|
||||||
"RULE("
|
|
||||||
"TARGET("
|
|
||||||
"VAR[BIM]"
|
|
||||||
"),DEPS("
|
|
||||||
"ARRAY(IDENT[hello.cpp],IDENT[world.cpp])"
|
|
||||||
"),BLOCK("
|
|
||||||
"CMD("
|
|
||||||
"IDENT[g++],INDEX(VAR[BIM],IDENT[.c],IDENT[.o]),IDENT[-o],IDENT[hello.elf]"
|
|
||||||
"),CMD("
|
|
||||||
"IDENT[ls]"
|
|
||||||
")"
|
|
||||||
")))",
|
|
||||||
ss.str());
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue