Commit e31923da authored by Alastair Robertson's avatar Alastair Robertson

Add variables and assignment to grammar

parent 76333562
...@@ -6,36 +6,49 @@ namespace ast { ...@@ -6,36 +6,49 @@ namespace ast {
void Integer::print_ast(std::ostream &out, unsigned int depth) const void Integer::print_ast(std::ostream &out, unsigned int depth) const
{ {
out << "int: " << n << std::endl; std::string indent(depth, ' ');
out << indent << "int: " << n << std::endl;
} }
void Identifier::print_ast(std::ostream &out, unsigned int depth) const void Variable::print_ast(std::ostream &out, unsigned int depth) const
{ {
out << "ident: " << ident << std::endl; std::string indent(depth, ' ');
out << indent << "var: " << ident << std::endl;
if (vargs != nullptr) {
for (Expression *expr : *vargs) {
expr->print_ast(out, depth+1);
}
}
}
void ExprStatement::print_ast(std::ostream &out, unsigned int depth) const
{
std::string indent(depth, ' ');
expr->print_ast(out, depth);
} }
void Statement::print_ast(std::ostream &out, unsigned int depth) const void AssignStatement::print_ast(std::ostream &out, unsigned int depth) const
{ {
out << "stmt" << std::endl; std::string indent(depth, ' ');
out << std::string(depth, ' '); out << indent << "=" << std::endl;
var->print_ast(out, depth+1);
expr->print_ast(out, depth+1); expr->print_ast(out, depth+1);
} }
void Probe::print_ast(std::ostream &out, unsigned int depth) const void Probe::print_ast(std::ostream &out, unsigned int depth) const
{ {
out << "Probe" << std::endl; std::string indent(depth, ' ');
out << indent << "Probe" << std::endl;
for (Statement *stmt : *stmts) { for (Statement *stmt : *stmts) {
out << std::string(depth, ' ');
stmt->print_ast(out, depth+1); stmt->print_ast(out, depth+1);
} }
} }
void Program::print_ast(std::ostream &out, unsigned int depth) const void Program::print_ast(std::ostream &out, unsigned int depth) const
{ {
out << "Program" << std::endl; std::string indent(depth, ' ');
++depth; out << indent << "Program" << std::endl;
for (Probe *probe : *probes) { for (Probe *probe : *probes) {
out << std::string(depth, ' ');
probe->print_ast(out, depth+1); probe->print_ast(out, depth+1);
} }
} }
......
...@@ -16,6 +16,7 @@ public: ...@@ -16,6 +16,7 @@ public:
class Expression : public Node { class Expression : public Node {
}; };
using ExpressionList = std::vector<Expression *>;
class Integer : public Expression { class Integer : public Expression {
public: public:
...@@ -24,24 +25,37 @@ public: ...@@ -24,24 +25,37 @@ public:
int n; int n;
}; };
class Identifier : public Expression { class Variable : public Expression {
public: public:
explicit Identifier(std::string &ident) : ident(ident) { } explicit Variable(std::string &ident) : ident(ident), vargs(nullptr) { }
Variable(std::string &ident, ExpressionList *vargs) : ident(ident), vargs(vargs) { }
void print_ast(std::ostream &out, unsigned int depth = 0) const override; void print_ast(std::ostream &out, unsigned int depth = 0) const override;
std::string ident; std::string ident;
ExpressionList *vargs;
}; };
class Statement : public Node { class Statement : public Node {
};
using StatementList = std::vector<Statement *>;
class ExprStatement : public Statement {
public: public:
explicit Statement(Expression *expr) : expr(expr) { } explicit ExprStatement(Expression *expr) : expr(expr) { }
void print_ast(std::ostream &out, unsigned int depth = 0) const override; void print_ast(std::ostream &out, unsigned int depth = 0) const override;
Expression *expr; Expression *expr;
}; };
using StatementList = std::vector<Statement *>;
class AssignStatement : public Statement {
public:
AssignStatement(Variable *var, Expression *expr) : var(var), expr(expr) { }
void print_ast(std::ostream &out, unsigned int depth = 0) const override;
Variable *var;
Expression *expr;
};
class Probe : public Node { class Probe : public Node {
public: public:
Probe(std::string type, std::string attach_point, StatementList *stmts) Probe(std::string &type, std::string &attach_point, StatementList *stmts)
: type(type), attach_point(attach_point), stmts(stmts) { } : type(type), attach_point(attach_point), stmts(stmts) { }
void print_ast(std::ostream &out, unsigned int depth = 0) const override; void print_ast(std::ostream &out, unsigned int depth = 0) const override;
......
...@@ -32,6 +32,7 @@ using namespace ebpf::bpftrace; ...@@ -32,6 +32,7 @@ using namespace ebpf::bpftrace;
";" { return Parser::make_SEMI(loc); } ";" { return Parser::make_SEMI(loc); }
"{" { return Parser::make_LBRACE(loc); } "{" { return Parser::make_LBRACE(loc); }
"}" { return Parser::make_RBRACE(loc); } "}" { return Parser::make_RBRACE(loc); }
"=" { return Parser::make_ASSIGN(loc); }
. { driver.error(loc, std::string("invalid character: ")+std::string(yytext)); yyterminate(); } . { driver.error(loc, std::string("invalid character: ")+std::string(yytext)); yyterminate(); }
......
...@@ -12,6 +12,8 @@ int main(int argc, char *argv[]) ...@@ -12,6 +12,8 @@ int main(int argc, char *argv[])
result = driver.parse(argv[1]); result = driver.parse(argv[1]);
} }
driver.root_->print_ast(std::cout); if (!result)
driver.root_->print_ast(std::cout);
return result; return result;
} }
...@@ -42,6 +42,7 @@ void yyerror(ebpf::bpftrace::Driver &driver, const char *s); ...@@ -42,6 +42,7 @@ void yyerror(ebpf::bpftrace::Driver &driver, const char *s);
SEMI ";" SEMI ";"
LBRACE "{" LBRACE "{"
RBRACE "}" RBRACE "}"
ASSIGN "="
; ;
%token <std::string> IDENT "identifier" %token <std::string> IDENT "identifier"
...@@ -52,6 +53,8 @@ void yyerror(ebpf::bpftrace::Driver &driver, const char *s); ...@@ -52,6 +53,8 @@ void yyerror(ebpf::bpftrace::Driver &driver, const char *s);
%type <ast::Probe *> probe %type <ast::Probe *> probe
%type <ast::Statement *> stmt %type <ast::Statement *> stmt
%type <ast::Expression *> expr %type <ast::Expression *> expr
%type <ast::Variable *> var
%type <ast::ExpressionList *> vargs
%printer { yyoutput << %%; } <*>; %printer { yyoutput << %%; } <*>;
...@@ -76,13 +79,22 @@ stmts : stmts ";" stmt { $$ = $1; $1->push_back($3); } ...@@ -76,13 +79,22 @@ stmts : stmts ";" stmt { $$ = $1; $1->push_back($3); }
| stmt { $$ = new ast::StatementList; $$->push_back($1); } | stmt { $$ = new ast::StatementList; $$->push_back($1); }
; ;
stmt : expr { $$ = new ast::Statement($1); } stmt : expr { $$ = new ast::ExprStatement($1); }
| var "=" expr { $$ = new ast::AssignStatement($1, $3); }
; ;
expr : INT { $$ = new ast::Integer($1); } expr : INT { $$ = new ast::Integer($1); }
| IDENT { $$ = new ast::Identifier($1); } | var { $$ = $1; }
; ;
var : IDENT { $$ = new ast::Variable($1); }
| IDENT "[" vargs "]" { $$ = new ast::Variable($1, $3); }
;
vargs : vargs "," expr { $$ = $1; $1->push_back($3); }
| expr { $$ = new ast::ExpressionList; $$->push_back($1); }
;
%% %%
void ebpf::bpftrace::Parser::error(const location &l, const std::string &m) void ebpf::bpftrace::Parser::error(const location &l, const std::string &m)
......
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