Commit c2c9ade8 authored by Alastair Robertson's avatar Alastair Robertson

Parser: Accept "#include <file.h>" at start of script

parent 1585341b
...@@ -60,6 +60,10 @@ void Probe::accept(Visitor &v) { ...@@ -60,6 +60,10 @@ void Probe::accept(Visitor &v) {
v.visit(*this); v.visit(*this);
} }
void Include::accept(Visitor &v) {
v.visit(*this);
}
void Program::accept(Visitor &v) { void Program::accept(Visitor &v) {
v.visit(*this); v.visit(*this);
} }
......
...@@ -176,9 +176,20 @@ public: ...@@ -176,9 +176,20 @@ public:
}; };
using ProbeList = std::vector<Probe *>; using ProbeList = std::vector<Probe *>;
class Include : public Node {
public:
explicit Include(const std::string &file) : file(file) { }
std::string file;
void accept(Visitor &v) override;
};
using IncludeList = std::vector<Include *>;
class Program : public Node { class Program : public Node {
public: public:
explicit Program(ProbeList *probes) : probes(probes) { } Program(IncludeList *includes, ProbeList *probes)
: includes(includes), probes(probes) { }
IncludeList *includes;
ProbeList *probes; ProbeList *probes;
void accept(Visitor &v) override; void accept(Visitor &v) override;
...@@ -201,6 +212,7 @@ public: ...@@ -201,6 +212,7 @@ public:
virtual void visit(Predicate &pred) = 0; virtual void visit(Predicate &pred) = 0;
virtual void visit(AttachPoint &ap) = 0; virtual void visit(AttachPoint &ap) = 0;
virtual void visit(Probe &probe) = 0; virtual void visit(Probe &probe) = 0;
virtual void visit(Include &include) = 0;
virtual void visit(Program &program) = 0; virtual void visit(Program &program) = 0;
}; };
......
...@@ -410,11 +410,16 @@ void CodegenLLVM::visit(Probe &probe) ...@@ -410,11 +410,16 @@ void CodegenLLVM::visit(Probe &probe)
b_.CreateRet(ConstantInt::get(module_->getContext(), APInt(64, 0))); b_.CreateRet(ConstantInt::get(module_->getContext(), APInt(64, 0)));
} }
void CodegenLLVM::visit(Include &include)
{
}
void CodegenLLVM::visit(Program &program) void CodegenLLVM::visit(Program &program)
{ {
for (Probe *probe : *program.probes) { for (Include *include : *program.includes)
include->accept(*this);
for (Probe *probe : *program.probes)
probe->accept(*this); probe->accept(*this);
}
} }
AllocaInst *CodegenLLVM::getMapKey(Map &map) AllocaInst *CodegenLLVM::getMapKey(Map &map)
......
...@@ -41,6 +41,7 @@ public: ...@@ -41,6 +41,7 @@ public:
void visit(Predicate &pred) override; void visit(Predicate &pred) override;
void visit(AttachPoint &ap) override; void visit(AttachPoint &ap) override;
void visit(Probe &probe) override; void visit(Probe &probe) override;
void visit(Include &include) override;
void visit(Program &program) override; void visit(Program &program) override;
AllocaInst *getMapKey(Map &map); AllocaInst *getMapKey(Map &map);
AllocaInst *getQuantizeMapKey(Map &map, Value *log2); AllocaInst *getQuantizeMapKey(Map &map, Value *log2);
......
...@@ -131,8 +131,6 @@ void Printer::visit(AttachPoint &ap) ...@@ -131,8 +131,6 @@ void Printer::visit(AttachPoint &ap)
void Printer::visit(Probe &probe) void Printer::visit(Probe &probe)
{ {
std::string indent(depth_, ' ');
for (AttachPoint *ap : *probe.attach_points) { for (AttachPoint *ap : *probe.attach_points) {
ap->accept(*this); ap->accept(*this);
} }
...@@ -147,15 +145,22 @@ void Printer::visit(Probe &probe) ...@@ -147,15 +145,22 @@ void Printer::visit(Probe &probe)
--depth_; --depth_;
} }
void Printer::visit(Include &include)
{
std::string indent(depth_, ' ');
out_ << indent << "#include " << include.file << std::endl;
}
void Printer::visit(Program &program) void Printer::visit(Program &program)
{ {
std::string indent(depth_, ' '); std::string indent(depth_, ' ');
out_ << indent << "Program" << std::endl; out_ << indent << "Program" << std::endl;
++depth_; ++depth_;
for (Probe *probe : *program.probes) { for (Include *include : *program.includes)
include->accept(*this);
for (Probe *probe : *program.probes)
probe->accept(*this); probe->accept(*this);
}
--depth_; --depth_;
} }
......
...@@ -24,6 +24,7 @@ public: ...@@ -24,6 +24,7 @@ public:
void visit(Predicate &pred) override; void visit(Predicate &pred) override;
void visit(AttachPoint &ap) override; void visit(AttachPoint &ap) override;
void visit(Probe &probe) override; void visit(Probe &probe) override;
void visit(Include &include) override;
void visit(Program &program) override; void visit(Program &program) override;
int depth_ = 0; int depth_ = 0;
......
...@@ -425,11 +425,16 @@ void SemanticAnalyser::visit(Probe &probe) ...@@ -425,11 +425,16 @@ void SemanticAnalyser::visit(Probe &probe)
} }
} }
void SemanticAnalyser::visit(Include &include)
{
}
void SemanticAnalyser::visit(Program &program) void SemanticAnalyser::visit(Program &program)
{ {
for (Probe *probe : *program.probes) { for (Include *include : *program.includes)
include->accept(*this);
for (Probe *probe : *program.probes)
probe->accept(*this); probe->accept(*this);
}
} }
int SemanticAnalyser::analyse() int SemanticAnalyser::analyse()
......
...@@ -31,6 +31,7 @@ public: ...@@ -31,6 +31,7 @@ public:
void visit(Predicate &pred) override; void visit(Predicate &pred) override;
void visit(AttachPoint &ap) override; void visit(AttachPoint &ap) override;
void visit(Probe &probe) override; void visit(Probe &probe) override;
void visit(Include &include) override;
void visit(Program &program) override; void visit(Program &program) override;
int analyse(); int analyse();
......
...@@ -25,6 +25,7 @@ hspace [ \t] ...@@ -25,6 +25,7 @@ hspace [ \t]
vspace [\n\r] vspace [\n\r]
space {hspace}|{vspace} space {hspace}|{vspace}
path :(\\.|[_\-\./a-zA-Z0-9])*: path :(\\.|[_\-\./a-zA-Z0-9])*:
header <(\\.|[_\-\./a-zA-Z0-9])*>
%x STR %x STR
%% %%
...@@ -39,6 +40,7 @@ path :(\\.|[_\-\./a-zA-Z0-9])*: ...@@ -39,6 +40,7 @@ path :(\\.|[_\-\./a-zA-Z0-9])*:
{ident} { return Parser::make_IDENT(yytext, loc); } {ident} { return Parser::make_IDENT(yytext, loc); }
{path} { return Parser::make_PATH(yytext, loc); } {path} { return Parser::make_PATH(yytext, loc); }
{header} { return Parser::make_HEADER(yytext, loc); }
{map} { return Parser::make_MAP(yytext, loc); } {map} { return Parser::make_MAP(yytext, loc); }
{var} { return Parser::make_VAR(yytext, loc); } {var} { return Parser::make_VAR(yytext, loc); }
{int} { return Parser::make_INT(strtoul(yytext, NULL, 0), loc); } {int} { return Parser::make_INT(strtoul(yytext, NULL, 0), loc); }
...@@ -71,6 +73,7 @@ path :(\\.|[_\-\./a-zA-Z0-9])*: ...@@ -71,6 +73,7 @@ path :(\\.|[_\-\./a-zA-Z0-9])*:
"^" { return Parser::make_BXOR(loc); } "^" { return Parser::make_BXOR(loc); }
"!" { return Parser::make_LNOT(loc); } "!" { return Parser::make_LNOT(loc); }
"~" { return Parser::make_BNOT(loc); } "~" { return Parser::make_BNOT(loc); }
"#include" { return Parser::make_INCLUDE(loc); }
\" { BEGIN(STR); string_buffer.clear(); } \" { BEGIN(STR); string_buffer.clear(); }
<STR>\" { BEGIN(INITIAL); return Parser::make_STRING(string_buffer, loc); } <STR>\" { BEGIN(INITIAL); return Parser::make_STRING(string_buffer, loc); }
......
...@@ -65,19 +65,23 @@ void yyerror(bpftrace::Driver &driver, const char *s); ...@@ -65,19 +65,23 @@ void yyerror(bpftrace::Driver &driver, const char *s);
BXOR "^" BXOR "^"
LNOT "!" LNOT "!"
BNOT "~" BNOT "~"
INCLUDE "#include"
; ;
%token <std::string> IDENT "identifier" %token <std::string> IDENT "identifier"
%token <std::string> PATH "path" %token <std::string> PATH "path"
%token <std::string> HEADER "header"
%token <std::string> STRING "string" %token <std::string> STRING "string"
%token <std::string> MAP "map" %token <std::string> MAP "map"
%token <std::string> VAR "variable" %token <std::string> VAR "variable"
%token <int> INT "integer" %token <int> INT "integer"
%type <ast::IncludeList *> includes
%type <ast::Include *> include
%type <ast::ProbeList *> probes %type <ast::ProbeList *> probes
%type <ast::StatementList *> block stmts
%type <ast::Probe *> probe %type <ast::Probe *> probe
%type <ast::Predicate *> pred %type <ast::Predicate *> pred
%type <ast::StatementList *> block stmts
%type <ast::Statement *> stmt %type <ast::Statement *> stmt
%type <ast::Expression *> expr %type <ast::Expression *> expr
%type <ast::Call *> call %type <ast::Call *> call
...@@ -104,7 +108,15 @@ void yyerror(bpftrace::Driver &driver, const char *s); ...@@ -104,7 +108,15 @@ void yyerror(bpftrace::Driver &driver, const char *s);
%% %%
program : probes { driver.root_ = new ast::Program($1); } program : includes probes { driver.root_ = new ast::Program($1, $2); }
;
includes : includes include { $$ = $1; $1->push_back($2); }
| { $$ = new ast::IncludeList; }
;
include : INCLUDE STRING { $$ = new ast::Include($2); }
| INCLUDE HEADER { $$ = new ast::Include($2.substr(1, $2.size()-2)); }
; ;
probes : probes probe { $$ = $1; $1->push_back($2); } probes : probes probe { $$ = $1; $1->push_back($2); }
......
...@@ -300,6 +300,41 @@ TEST(Parser, short_map_name) ...@@ -300,6 +300,41 @@ TEST(Parser, short_map_name)
" int: 1\n"); " int: 1\n");
} }
TEST(Parser, include)
{
test("#include <stdio.h> kprobe:sys_read { @x = 1 }",
"Program\n"
" #include stdio.h\n"
" kprobe:sys_read\n"
" =\n"
" map: @x\n"
" int: 1\n");
}
TEST(Parser, include_quote)
{
test("#include \"stdio.h\" kprobe:sys_read { @x = 1 }",
"Program\n"
" #include stdio.h\n"
" kprobe:sys_read\n"
" =\n"
" map: @x\n"
" int: 1\n");
}
TEST(Parser, include_multiple)
{
test("#include <stdio.h> #include \"blah\" #include <foo.h> kprobe:sys_read { @x = 1 }",
"Program\n"
" #include stdio.h\n"
" #include blah\n"
" #include foo.h\n"
" kprobe:sys_read\n"
" =\n"
" map: @x\n"
" int: 1\n");
}
} // namespace parser } // namespace parser
} // namespace test } // namespace test
} // namespace bpftrace } // namespace bpftrace
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment