mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
AST printer and command line tool, some fixes.
This commit is contained in:
parent
924f7c62bd
commit
98bdd74299
232
AST.cpp
232
AST.cpp
@ -21,3 +21,235 @@
|
||||
*/
|
||||
|
||||
#include <libsolidity/AST.h>
|
||||
#include <libsolidity/ASTVisitor.h>
|
||||
|
||||
namespace dev {
|
||||
namespace solidity {
|
||||
|
||||
void ContractDefinition::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this)) {
|
||||
listAccept(m_definedStructs, _visitor);
|
||||
listAccept(m_stateVariables, _visitor);
|
||||
listAccept(m_definedFunctions, _visitor);
|
||||
}
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void StructDefinition::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this)) {
|
||||
listAccept(m_members, _visitor);
|
||||
}
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void ParameterList::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this)) {
|
||||
listAccept(m_parameters, _visitor);
|
||||
}
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void FunctionDefinition::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this)) {
|
||||
m_parameters->accept(_visitor);
|
||||
if (m_returnParameters)
|
||||
m_returnParameters->accept(_visitor);
|
||||
m_body->accept(_visitor);
|
||||
}
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void VariableDeclaration::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this)) {
|
||||
if (m_type)
|
||||
m_type->accept(_visitor);
|
||||
}
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void TypeName::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
_visitor.visit(*this);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void ElementaryTypeName::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
_visitor.visit(*this);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void UserDefinedTypeName::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
_visitor.visit(*this);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void Mapping::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this)) {
|
||||
m_keyType->accept(_visitor);
|
||||
m_valueType->accept(_visitor);
|
||||
}
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void Statement::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
_visitor.visit(*this);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void Block::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this)) {
|
||||
listAccept(m_statements, _visitor);
|
||||
}
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void IfStatement::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this)) {
|
||||
m_condition->accept(_visitor);
|
||||
m_trueBody->accept(_visitor);
|
||||
if (m_falseBody)
|
||||
m_falseBody->accept(_visitor);
|
||||
}
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void BreakableStatement::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
_visitor.visit(*this);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void WhileStatement::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this)) {
|
||||
m_condition->accept(_visitor);
|
||||
m_body->accept(_visitor);
|
||||
}
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void Continue::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
_visitor.visit(*this);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void Break::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
_visitor.visit(*this);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void Return::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this)) {
|
||||
if (m_expression)
|
||||
m_expression->accept(_visitor);
|
||||
}
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void VariableDefinition::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this)) {
|
||||
m_variable->accept(_visitor);
|
||||
if (m_value)
|
||||
m_value->accept(_visitor);
|
||||
}
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void Expression::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
_visitor.visit(*this);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void Assignment::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this)) {
|
||||
m_leftHandSide->accept(_visitor);
|
||||
m_rightHandSide->accept(_visitor);
|
||||
}
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void UnaryOperation::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this)) {
|
||||
m_subExpression->accept(_visitor);
|
||||
}
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void BinaryOperation::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this)) {
|
||||
m_left->accept(_visitor);
|
||||
m_right->accept(_visitor);
|
||||
}
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void FunctionCall::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this)) {
|
||||
m_expression->accept(_visitor);
|
||||
listAccept(m_arguments, _visitor);
|
||||
}
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void MemberAccess::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this)) {
|
||||
m_expression->accept(_visitor);
|
||||
}
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void IndexAccess::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this)) {
|
||||
m_base->accept(_visitor);
|
||||
m_index->accept(_visitor);
|
||||
}
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void PrimaryExpression::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
_visitor.visit(*this);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void Identifier::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
_visitor.visit(*this);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void ElementaryTypeNameExpression::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
_visitor.visit(*this);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void Literal::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
_visitor.visit(*this);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
} }
|
||||
|
118
AST.h
118
AST.h
@ -26,26 +26,14 @@
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#include <libsolidity/ASTForward.h>
|
||||
#include <libsolidity/BaseTypes.h>
|
||||
#include <libsolidity/Token.h>
|
||||
|
||||
namespace dev {
|
||||
namespace solidity {
|
||||
|
||||
// Used as pointers to AST nodes, to be replaced by more clever pointers, e.g. pointers which do
|
||||
// not do reference counting but point to a special memory area that is completely released
|
||||
// explicitly.
|
||||
template <class T>
|
||||
using ptr = std::shared_ptr<T>;
|
||||
template <class T>
|
||||
using vecptr = std::vector<ptr<T>>;
|
||||
|
||||
class VariableDeclaration;
|
||||
class StructDefinition;
|
||||
class FunctionDefinition;
|
||||
class TypeName;
|
||||
class Block;
|
||||
class Expression;
|
||||
class ASTVisitor;
|
||||
|
||||
class ASTNode
|
||||
{
|
||||
@ -56,7 +44,13 @@ public:
|
||||
|
||||
virtual ~ASTNode() {}
|
||||
|
||||
Location getLocation() const { return m_location; }
|
||||
virtual void accept(ASTVisitor& _visitor) = 0;
|
||||
template <class T>
|
||||
static void listAccept(vecptr<T>& _list, ASTVisitor& _visitor) {
|
||||
for (ptr<T>& element : _list) element->accept(_visitor);
|
||||
}
|
||||
|
||||
Location const& getLocation() const { return m_location; }
|
||||
private:
|
||||
Location m_location;
|
||||
};
|
||||
@ -65,7 +59,7 @@ class ContractDefinition : public ASTNode
|
||||
{
|
||||
public:
|
||||
ContractDefinition(Location const& _location,
|
||||
std::string const& _name,
|
||||
ptr<ASTString> const& _name,
|
||||
vecptr<StructDefinition> const& _definedStructs,
|
||||
vecptr<VariableDeclaration> const& _stateVariables,
|
||||
vecptr<FunctionDefinition> const& _definedFunctions)
|
||||
@ -75,8 +69,11 @@ public:
|
||||
m_definedFunctions(_definedFunctions)
|
||||
{}
|
||||
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
|
||||
const ASTString& getName() const { return *m_name; }
|
||||
private:
|
||||
std::string m_name;
|
||||
ptr<ASTString> m_name;
|
||||
vecptr<StructDefinition> m_definedStructs;
|
||||
vecptr<VariableDeclaration> m_stateVariables;
|
||||
vecptr<FunctionDefinition> m_definedFunctions;
|
||||
@ -86,12 +83,15 @@ class StructDefinition : public ASTNode
|
||||
{
|
||||
public:
|
||||
StructDefinition(Location const& _location,
|
||||
std::string const& _name,
|
||||
ptr<ASTString> const& _name,
|
||||
vecptr<VariableDeclaration> const& _members)
|
||||
: ASTNode(_location), m_name(_name), m_members(_members)
|
||||
{}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
|
||||
const ASTString& getName() const { return *m_name; }
|
||||
private:
|
||||
std::string m_name;
|
||||
ptr<ASTString> m_name;
|
||||
vecptr<VariableDeclaration> m_members;
|
||||
};
|
||||
|
||||
@ -104,6 +104,7 @@ public:
|
||||
ParameterList(Location const& _location, vecptr<VariableDeclaration> const& _parameters)
|
||||
: ASTNode(_location), m_parameters(_parameters)
|
||||
{}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
private:
|
||||
vecptr<VariableDeclaration> m_parameters;
|
||||
};
|
||||
@ -111,7 +112,7 @@ private:
|
||||
class FunctionDefinition : public ASTNode
|
||||
{
|
||||
public:
|
||||
FunctionDefinition(Location const& _location, std::string const& _name, bool _isPublic,
|
||||
FunctionDefinition(Location const& _location, ptr<ASTString> const& _name, bool _isPublic,
|
||||
ptr<ParameterList> const& _parameters,
|
||||
bool _isDeclaredConst,
|
||||
ptr<ParameterList> const& _returnParameters,
|
||||
@ -120,8 +121,13 @@ public:
|
||||
m_isDeclaredConst(_isDeclaredConst), m_returnParameters(_returnParameters),
|
||||
m_body(_body)
|
||||
{}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
|
||||
const ASTString& getName() const { return *m_name; }
|
||||
bool isPublic() const { return m_isPublic; }
|
||||
bool isDeclaredConst() const { return m_isDeclaredConst; }
|
||||
private:
|
||||
std::string m_name;
|
||||
ptr<ASTString> m_name;
|
||||
bool m_isPublic;
|
||||
ptr<ParameterList> m_parameters;
|
||||
bool m_isDeclaredConst;
|
||||
@ -134,12 +140,15 @@ class VariableDeclaration : public ASTNode
|
||||
public:
|
||||
VariableDeclaration(Location const& _location,
|
||||
ptr<TypeName> const& _type,
|
||||
std::string const& _name)
|
||||
ptr<ASTString> const& _name)
|
||||
: ASTNode(_location), m_type(_type), m_name(_name)
|
||||
{}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
|
||||
const ASTString& getName() const { return *m_name; }
|
||||
private:
|
||||
ptr<TypeName> m_type; ///< can be empty ("var")
|
||||
std::string m_name;
|
||||
ptr<ASTString> m_name;
|
||||
};
|
||||
|
||||
/// types
|
||||
@ -149,6 +158,7 @@ class TypeName : public ASTNode
|
||||
{
|
||||
public:
|
||||
explicit TypeName(Location const& _location) : ASTNode(_location) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
};
|
||||
|
||||
/// any pre-defined type that is not a mapping
|
||||
@ -158,6 +168,9 @@ public:
|
||||
explicit ElementaryTypeName(Location const& _location, Token::Value _type)
|
||||
: TypeName(_location), m_type(_type)
|
||||
{}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
|
||||
Token::Value getType() const { return m_type; }
|
||||
private:
|
||||
Token::Value m_type;
|
||||
};
|
||||
@ -165,11 +178,14 @@ private:
|
||||
class UserDefinedTypeName : public TypeName
|
||||
{
|
||||
public:
|
||||
UserDefinedTypeName(Location const& _location, std::string const& _name)
|
||||
UserDefinedTypeName(Location const& _location, ptr<ASTString> const& _name)
|
||||
: TypeName(_location), m_name(_name)
|
||||
{}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
|
||||
const ASTString& getName() const { return *m_name; }
|
||||
private:
|
||||
std::string m_name;
|
||||
ptr<ASTString> m_name;
|
||||
};
|
||||
|
||||
class Mapping : public TypeName
|
||||
@ -179,6 +195,7 @@ public:
|
||||
ptr<TypeName> const& _valueType)
|
||||
: TypeName(_location), m_keyType(_keyType), m_valueType(_valueType)
|
||||
{}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
private:
|
||||
ptr<ElementaryTypeName> m_keyType;
|
||||
ptr<TypeName> m_valueType;
|
||||
@ -193,6 +210,7 @@ class Statement : public ASTNode
|
||||
{
|
||||
public:
|
||||
explicit Statement(Location const& _location) : ASTNode(_location) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
};
|
||||
|
||||
class Block : public Statement
|
||||
@ -201,6 +219,7 @@ public:
|
||||
Block(Location const& _location, vecptr<Statement> const& _statements)
|
||||
: Statement(_location), m_statements(_statements)
|
||||
{}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
private:
|
||||
vecptr<Statement> m_statements;
|
||||
};
|
||||
@ -213,16 +232,18 @@ public:
|
||||
: Statement(_location), m_condition(_condition),
|
||||
m_trueBody(_trueBody), m_falseBody(_falseBody)
|
||||
{}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
private:
|
||||
ptr<Expression> m_condition;
|
||||
ptr<Statement> m_trueBody;
|
||||
ptr<Statement> m_falseBody;
|
||||
ptr<Statement> m_falseBody; //< "else" part, optional
|
||||
};
|
||||
|
||||
class BreakableStatement : public Statement
|
||||
{
|
||||
public:
|
||||
BreakableStatement(Location const& _location) : Statement(_location) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
};
|
||||
|
||||
class WhileStatement : public BreakableStatement
|
||||
@ -232,6 +253,7 @@ public:
|
||||
ptr<Statement> const& _body)
|
||||
: BreakableStatement(_location), m_condition(_condition), m_body(_body)
|
||||
{}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
private:
|
||||
ptr<Expression> m_condition;
|
||||
ptr<Statement> m_body;
|
||||
@ -241,12 +263,14 @@ class Continue : public Statement
|
||||
{
|
||||
public:
|
||||
Continue(Location const& _location) : Statement(_location) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
};
|
||||
|
||||
class Break : public Statement
|
||||
{
|
||||
public:
|
||||
Break(Location const& _location) : Statement(_location) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
};
|
||||
|
||||
class Return : public Statement
|
||||
@ -255,8 +279,9 @@ public:
|
||||
Return(Location const& _location, ptr<Expression> _expression)
|
||||
: Statement(_location), m_expression(_expression)
|
||||
{}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
private:
|
||||
ptr<Expression> m_expression;
|
||||
ptr<Expression> m_expression; //< value to return, optional
|
||||
};
|
||||
|
||||
class VariableDefinition : public Statement
|
||||
@ -266,6 +291,7 @@ public:
|
||||
ptr<Expression> _value)
|
||||
: Statement(_location), m_variable(_variable), m_value(_value)
|
||||
{}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
private:
|
||||
ptr<VariableDeclaration> m_variable;
|
||||
ptr<Expression> m_value; ///< can be missing
|
||||
@ -275,6 +301,7 @@ class Expression : public Statement
|
||||
{
|
||||
public:
|
||||
Expression(Location const& _location) : Statement(_location) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
};
|
||||
|
||||
/// @}
|
||||
@ -290,6 +317,9 @@ public:
|
||||
: Expression(_location), m_leftHandSide(_leftHandSide),
|
||||
m_assigmentOperator(_assignmentOperator), m_rightHandSide(_rightHandSide)
|
||||
{}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
|
||||
Token::Value getAssignmentOperator() const { return m_assigmentOperator; }
|
||||
private:
|
||||
ptr<Expression> m_leftHandSide;
|
||||
Token::Value m_assigmentOperator;
|
||||
@ -304,7 +334,10 @@ public:
|
||||
: Expression(_location), m_operator(_operator),
|
||||
m_subExpression(_subExpression), m_isPrefix(_isPrefix)
|
||||
{}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
|
||||
Token::Value getOperator() const { return m_operator; }
|
||||
bool isPrefixOperation() const { return m_isPrefix; }
|
||||
private:
|
||||
Token::Value m_operator;
|
||||
ptr<Expression> m_subExpression;
|
||||
@ -318,6 +351,9 @@ public:
|
||||
Token::Value _operator, ptr<Expression> const& _right)
|
||||
: Expression(_location), m_left(_left), m_operator(_operator), m_right(_right)
|
||||
{}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
|
||||
Token::Value getOperator() const { return m_operator; }
|
||||
private:
|
||||
ptr<Expression> m_left;
|
||||
Token::Value m_operator;
|
||||
@ -332,6 +368,7 @@ public:
|
||||
vecptr<Expression> const& _arguments)
|
||||
: Expression(_location), m_expression(_expression), m_arguments(_arguments)
|
||||
{}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
private:
|
||||
ptr<Expression> m_expression;
|
||||
vecptr<Expression> m_arguments;
|
||||
@ -341,12 +378,14 @@ class MemberAccess : public Expression
|
||||
{
|
||||
public:
|
||||
MemberAccess(Location const& _location, ptr<Expression> _expression,
|
||||
std::string const& _memberName)
|
||||
ptr<ASTString> const& _memberName)
|
||||
: Expression(_location), m_expression(_expression), m_memberName(_memberName)
|
||||
{}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
const ASTString& getMemberName() const { return *m_memberName; }
|
||||
private:
|
||||
ptr<Expression> m_expression;
|
||||
std::string m_memberName;
|
||||
ptr<ASTString> m_memberName;
|
||||
};
|
||||
|
||||
class IndexAccess : public Expression
|
||||
@ -356,6 +395,7 @@ public:
|
||||
ptr<Expression> const& _index)
|
||||
: Expression(_location), m_base(_base), m_index(_index)
|
||||
{}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
private:
|
||||
ptr<Expression> m_base;
|
||||
ptr<Expression> m_index;
|
||||
@ -365,15 +405,19 @@ class PrimaryExpression : public Expression
|
||||
{
|
||||
public:
|
||||
PrimaryExpression(Location const& _location) : Expression(_location) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
};
|
||||
|
||||
class Identifier : public PrimaryExpression
|
||||
{
|
||||
public:
|
||||
Identifier(Location const& _location, std::string const& _name)
|
||||
Identifier(Location const& _location, ptr<ASTString> const& _name)
|
||||
: PrimaryExpression(_location), m_name(_name) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
|
||||
ASTString const& getName() const { return *m_name; }
|
||||
private:
|
||||
std::string m_name;
|
||||
ptr<ASTString> m_name;
|
||||
};
|
||||
|
||||
class ElementaryTypeNameExpression : public PrimaryExpression
|
||||
@ -381,6 +425,9 @@ class ElementaryTypeNameExpression : public PrimaryExpression
|
||||
public:
|
||||
ElementaryTypeNameExpression(Location const& _location, Token::Value _type)
|
||||
: PrimaryExpression(_location), m_type(_type) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
|
||||
Token::Value getType() const { return m_type; }
|
||||
private:
|
||||
Token::Value m_type;
|
||||
};
|
||||
@ -388,15 +435,18 @@ private:
|
||||
class Literal : public PrimaryExpression
|
||||
{
|
||||
public:
|
||||
Literal(Location const& _location, Token::Value _token, std::string const& _value)
|
||||
Literal(Location const& _location, Token::Value _token, ptr<ASTString> const& _value)
|
||||
: PrimaryExpression(_location), m_token(_token), m_value(_value)
|
||||
{}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
|
||||
Token::Value getToken() const { return m_token; }
|
||||
ASTString const& getValue() const { return *m_value; }
|
||||
private:
|
||||
Token::Value m_token;
|
||||
std::string m_value;
|
||||
ptr<ASTString> m_value;
|
||||
};
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
} }
|
||||
|
53
ASTForward.h
Normal file
53
ASTForward.h
Normal file
@ -0,0 +1,53 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
// Forward-declare all AST node types
|
||||
|
||||
namespace dev {
|
||||
namespace solidity {
|
||||
|
||||
class ASTNode;
|
||||
class ContractDefinition;
|
||||
class StructDefinition;
|
||||
class ParameterList;
|
||||
class FunctionDefinition;
|
||||
class VariableDeclaration;
|
||||
class TypeName;
|
||||
class ElementaryTypeName;
|
||||
class UserDefinedTypeName;
|
||||
class Mapping;
|
||||
class Statement;
|
||||
class Block;
|
||||
class IfStatement;
|
||||
class BreakableStatement;
|
||||
class WhileStatement;
|
||||
class Continue;
|
||||
class Break;
|
||||
class Return;
|
||||
class VariableDefinition;
|
||||
class Expression;
|
||||
class Assignment;
|
||||
class UnaryOperation;
|
||||
class BinaryOperation;
|
||||
class FunctionCall;
|
||||
class MemberAccess;
|
||||
class IndexAccess;
|
||||
class PrimaryExpression;
|
||||
class ElementaryTypeNameExpression;
|
||||
class Literal;
|
||||
|
||||
// Used as pointers to AST nodes, to be replaced by more clever pointers, e.g. pointers which do
|
||||
// not do reference counting but point to a special memory area that is completely released
|
||||
// explicitly.
|
||||
template <class T>
|
||||
using ptr = std::shared_ptr<T>;
|
||||
template <class T>
|
||||
using vecptr = std::vector<ptr<T>>;
|
||||
|
||||
using ASTString = std::string;
|
||||
|
||||
|
||||
} }
|
388
ASTPrinter.cpp
Normal file
388
ASTPrinter.cpp
Normal file
@ -0,0 +1,388 @@
|
||||
#include <libsolidity/ASTPrinter.h>
|
||||
#include <libsolidity/AST.h>
|
||||
|
||||
namespace dev {
|
||||
namespace solidity {
|
||||
|
||||
ASTPrinter::ASTPrinter(ptr<ASTNode> _ast, const std::string& _source)
|
||||
: m_indentation(0), m_source(_source), m_ast(_ast)
|
||||
{
|
||||
}
|
||||
|
||||
void ASTPrinter::print(std::ostream& _stream)
|
||||
{
|
||||
m_ostream = &_stream;
|
||||
m_ast->accept(*this);
|
||||
m_ostream = nullptr;
|
||||
}
|
||||
|
||||
|
||||
bool ASTPrinter::visit(ContractDefinition& _node)
|
||||
{
|
||||
writeLine("ContractDefinition \"" + _node.getName() + "\"");
|
||||
printSourcePart(_node);
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(StructDefinition& _node)
|
||||
{
|
||||
writeLine("StructDefinition \"" + _node.getName() + "\"");
|
||||
printSourcePart(_node);
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(ParameterList& _node)
|
||||
{
|
||||
writeLine("ParameterList");
|
||||
printSourcePart(_node);
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(FunctionDefinition& _node)
|
||||
{
|
||||
writeLine("FunctionDefinition \"" + _node.getName() + "\"" +
|
||||
(_node.isPublic() ? " - public" : "") +
|
||||
(_node.isDeclaredConst() ? " - const" : ""));
|
||||
printSourcePart(_node);
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(VariableDeclaration& _node)
|
||||
{
|
||||
writeLine("VariableDeclaration \"" + _node.getName() + "\"");
|
||||
printSourcePart(_node);
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(TypeName& _node)
|
||||
{
|
||||
writeLine("TypeName");
|
||||
printSourcePart(_node);
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(ElementaryTypeName& _node)
|
||||
{
|
||||
writeLine(std::string("ElementaryTypeName ") + Token::String(_node.getType()));
|
||||
printSourcePart(_node);
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(UserDefinedTypeName& _node)
|
||||
{
|
||||
writeLine("UserDefinedTypeName \"" + _node.getName() + "\"");
|
||||
printSourcePart(_node);
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(Mapping& _node)
|
||||
{
|
||||
writeLine("Mapping");
|
||||
printSourcePart(_node);
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(Statement& _node)
|
||||
{
|
||||
writeLine("Statement");
|
||||
printSourcePart(_node);
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(Block& _node)
|
||||
{
|
||||
writeLine("Block");
|
||||
printSourcePart(_node);
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(IfStatement& _node)
|
||||
{
|
||||
writeLine("IfStatement");
|
||||
printSourcePart(_node);
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(BreakableStatement& _node)
|
||||
{
|
||||
writeLine("BreakableStatement");
|
||||
printSourcePart(_node);
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(WhileStatement& _node)
|
||||
{
|
||||
writeLine("WhileStatement");
|
||||
printSourcePart(_node);
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(Continue& _node)
|
||||
{
|
||||
writeLine("Continue");
|
||||
printSourcePart(_node);
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(Break& _node)
|
||||
{
|
||||
writeLine("Break");
|
||||
printSourcePart(_node);
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(Return& _node)
|
||||
{
|
||||
writeLine("Return");
|
||||
printSourcePart(_node);
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(VariableDefinition& _node)
|
||||
{
|
||||
writeLine("VariableDefinition");
|
||||
printSourcePart(_node);
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(Expression& _node)
|
||||
{
|
||||
writeLine("Expression");
|
||||
printSourcePart(_node);
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(Assignment& _node)
|
||||
{
|
||||
writeLine(std::string("Assignment using operator ") + Token::String(_node.getAssignmentOperator()));
|
||||
printSourcePart(_node);
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(UnaryOperation& _node)
|
||||
{
|
||||
writeLine(std::string("UnaryOperation (") + (_node.isPrefixOperation() ? "prefix" : "postfix") +
|
||||
") " + Token::String(_node.getOperator()));
|
||||
printSourcePart(_node);
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(BinaryOperation& _node)
|
||||
{
|
||||
writeLine(std::string("BinaryOperation using operator ") + Token::String(_node.getOperator()));
|
||||
printSourcePart(_node);
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(FunctionCall& _node)
|
||||
{
|
||||
writeLine("FunctionCall");
|
||||
printSourcePart(_node);
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(MemberAccess& _node)
|
||||
{
|
||||
writeLine("MemberAccess to member " + _node.getMemberName());
|
||||
printSourcePart(_node);
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(IndexAccess& _node)
|
||||
{
|
||||
writeLine("IndexAccess");
|
||||
printSourcePart(_node);
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(PrimaryExpression& _node)
|
||||
{
|
||||
writeLine("PrimaryExpression");
|
||||
printSourcePart(_node);
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(ElementaryTypeNameExpression& _node)
|
||||
{
|
||||
writeLine(std::string("ElementaryTypeNameExpression ") + Token::String(_node.getType()));
|
||||
printSourcePart(_node);
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(Literal& _node)
|
||||
{
|
||||
const char* tokenString = Token::String(_node.getToken());
|
||||
if (tokenString == nullptr)
|
||||
tokenString = "----";
|
||||
writeLine(std::string("Literal, token: ") + tokenString + " value: " + _node.getValue());
|
||||
printSourcePart(_node);
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(ASTNode&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
// @todo instead of this, we could make the default implementation of endVisit call the
|
||||
// superclass' endVisit
|
||||
void ASTPrinter::endVisit(ContractDefinition&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(StructDefinition&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(ParameterList&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(FunctionDefinition&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(VariableDeclaration&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(TypeName&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(ElementaryTypeName&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(UserDefinedTypeName&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(Mapping&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(Statement&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(Block&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(IfStatement&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(BreakableStatement&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(WhileStatement&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(Continue&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(Break&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(Return&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(VariableDefinition&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(Expression&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(Assignment&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(UnaryOperation&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(BinaryOperation&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(FunctionCall&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(MemberAccess&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(IndexAccess&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(PrimaryExpression&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(ElementaryTypeNameExpression&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(Literal&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::printSourcePart(ASTNode const& _node)
|
||||
{
|
||||
if (!m_source.empty()) {
|
||||
Location const& location(_node.getLocation());
|
||||
*m_ostream << getIndentation() << " Source: |"
|
||||
<< m_source.substr(location.start, location.end - location.start) << "|\n";
|
||||
}
|
||||
}
|
||||
|
||||
std::string ASTPrinter::getIndentation() const
|
||||
{
|
||||
return std::string(m_indentation * 2, ' ');
|
||||
}
|
||||
|
||||
void ASTPrinter::writeLine(const std::string& _line)
|
||||
{
|
||||
*m_ostream << getIndentation() << _line << '\n';
|
||||
}
|
||||
|
||||
} }
|
88
ASTPrinter.h
Normal file
88
ASTPrinter.h
Normal file
@ -0,0 +1,88 @@
|
||||
#pragma once
|
||||
|
||||
#include <ostream>
|
||||
#include <libsolidity/ASTVisitor.h>
|
||||
|
||||
namespace dev {
|
||||
namespace solidity {
|
||||
|
||||
class ASTPrinter : public ASTVisitor
|
||||
{
|
||||
public:
|
||||
/// Create a printer for the given abstract syntax tree. If the source is specified,
|
||||
/// the corresponding parts of the source are printed with each node.
|
||||
ASTPrinter(ptr<ASTNode> _ast, const std::string& _source = std::string());
|
||||
/// Output the string representation of the AST to _stream.
|
||||
void print(std::ostream& _stream);
|
||||
|
||||
bool visit(ContractDefinition& _node);
|
||||
bool visit(StructDefinition& _node);
|
||||
bool visit(ParameterList& _node);
|
||||
bool visit(FunctionDefinition& _node);
|
||||
bool visit(VariableDeclaration& _node);
|
||||
bool visit(TypeName& _node);
|
||||
bool visit(ElementaryTypeName& _node);
|
||||
bool visit(UserDefinedTypeName& _node);
|
||||
bool visit(Mapping& _node);
|
||||
bool visit(Statement& _node);
|
||||
bool visit(Block& _node);
|
||||
bool visit(IfStatement& _node);
|
||||
bool visit(BreakableStatement& _node);
|
||||
bool visit(WhileStatement& _node);
|
||||
bool visit(Continue& _node);
|
||||
bool visit(Break& _node);
|
||||
bool visit(Return& _node);
|
||||
bool visit(VariableDefinition& _node);
|
||||
bool visit(Expression& _node);
|
||||
bool visit(Assignment& _node);
|
||||
bool visit(UnaryOperation& _node);
|
||||
bool visit(BinaryOperation& _node);
|
||||
bool visit(FunctionCall& _node);
|
||||
bool visit(MemberAccess& _node);
|
||||
bool visit(IndexAccess& _node);
|
||||
bool visit(PrimaryExpression& _node);
|
||||
bool visit(ElementaryTypeNameExpression& _node);
|
||||
bool visit(Literal& _node);
|
||||
|
||||
void endVisit(ASTNode & _node);
|
||||
void endVisit(ContractDefinition&);
|
||||
void endVisit(StructDefinition&);
|
||||
void endVisit(ParameterList&);
|
||||
void endVisit(FunctionDefinition&);
|
||||
void endVisit(VariableDeclaration&);
|
||||
void endVisit(TypeName&);
|
||||
void endVisit(ElementaryTypeName&);
|
||||
void endVisit(UserDefinedTypeName&);
|
||||
void endVisit(Mapping&);
|
||||
void endVisit(Statement&);
|
||||
void endVisit(Block&);
|
||||
void endVisit(IfStatement&);
|
||||
void endVisit(BreakableStatement&);
|
||||
void endVisit(WhileStatement&);
|
||||
void endVisit(Continue&);
|
||||
void endVisit(Break&);
|
||||
void endVisit(Return&);
|
||||
void endVisit(VariableDefinition&);
|
||||
void endVisit(Expression&);
|
||||
void endVisit(Assignment&);
|
||||
void endVisit(UnaryOperation&);
|
||||
void endVisit(BinaryOperation&);
|
||||
void endVisit(FunctionCall&);
|
||||
void endVisit(MemberAccess&);
|
||||
void endVisit(IndexAccess&);
|
||||
void endVisit(PrimaryExpression&);
|
||||
void endVisit(ElementaryTypeNameExpression&);
|
||||
void endVisit(Literal&);
|
||||
|
||||
private:
|
||||
void printSourcePart(ASTNode const& _node);
|
||||
std::string getIndentation() const;
|
||||
void writeLine(std::string const& _line);
|
||||
bool goDeeper() { m_indentation++; return true; }
|
||||
int m_indentation;
|
||||
std::string m_source;
|
||||
ptr<ASTNode> m_ast;
|
||||
std::ostream* m_ostream;
|
||||
};
|
||||
|
||||
} }
|
76
ASTVisitor.h
Normal file
76
ASTVisitor.h
Normal file
@ -0,0 +1,76 @@
|
||||
#pragma once
|
||||
|
||||
#include <libsolidity/ASTForward.h>
|
||||
#include <string>
|
||||
|
||||
namespace dev {
|
||||
namespace solidity {
|
||||
|
||||
class ASTVisitor {
|
||||
public:
|
||||
/// These functions are called after a call to ASTNode::accept,
|
||||
/// first visit, then (if visit returns true) recursively for all
|
||||
/// child nodes in document order (exception for contracts) and then
|
||||
/// endVisit.
|
||||
virtual bool visit(ASTNode&) { return true; }
|
||||
virtual bool visit(ContractDefinition&) { return true; }
|
||||
virtual bool visit(StructDefinition&) { return true; }
|
||||
virtual bool visit(ParameterList&) { return true; }
|
||||
virtual bool visit(FunctionDefinition&) { return true; }
|
||||
virtual bool visit(VariableDeclaration&) { return true; }
|
||||
virtual bool visit(TypeName&) { return true; }
|
||||
virtual bool visit(ElementaryTypeName&) { return true; }
|
||||
virtual bool visit(UserDefinedTypeName&) { return true; }
|
||||
virtual bool visit(Mapping&) { return true; }
|
||||
virtual bool visit(Statement&) { return true; }
|
||||
virtual bool visit(Block&) { return true; }
|
||||
virtual bool visit(IfStatement&) { return true; }
|
||||
virtual bool visit(BreakableStatement&) { return true; }
|
||||
virtual bool visit(WhileStatement&) { return true; }
|
||||
virtual bool visit(Continue&) { return true; }
|
||||
virtual bool visit(Break&) { return true; }
|
||||
virtual bool visit(Return&) { return true; }
|
||||
virtual bool visit(VariableDefinition&) { return true; }
|
||||
virtual bool visit(Expression&) { return true; }
|
||||
virtual bool visit(Assignment&) { return true; }
|
||||
virtual bool visit(UnaryOperation&) { return true; }
|
||||
virtual bool visit(BinaryOperation&) { return true; }
|
||||
virtual bool visit(FunctionCall&) { return true; }
|
||||
virtual bool visit(MemberAccess&) { return true; }
|
||||
virtual bool visit(IndexAccess&) { return true; }
|
||||
virtual bool visit(PrimaryExpression&) { return true; }
|
||||
virtual bool visit(ElementaryTypeNameExpression&) { return true; }
|
||||
virtual bool visit(Literal&) { return true; }
|
||||
|
||||
virtual void endVisit(ASTNode&) { }
|
||||
virtual void endVisit(ContractDefinition&) { }
|
||||
virtual void endVisit(StructDefinition&) { }
|
||||
virtual void endVisit(ParameterList&) { }
|
||||
virtual void endVisit(FunctionDefinition&) { }
|
||||
virtual void endVisit(VariableDeclaration&) { }
|
||||
virtual void endVisit(TypeName&) { }
|
||||
virtual void endVisit(ElementaryTypeName&) { }
|
||||
virtual void endVisit(UserDefinedTypeName&) { }
|
||||
virtual void endVisit(Mapping&) { }
|
||||
virtual void endVisit(Statement&) { }
|
||||
virtual void endVisit(Block&) { }
|
||||
virtual void endVisit(IfStatement&) { }
|
||||
virtual void endVisit(BreakableStatement&) { }
|
||||
virtual void endVisit(WhileStatement&) { }
|
||||
virtual void endVisit(Continue&) { }
|
||||
virtual void endVisit(Break&) { }
|
||||
virtual void endVisit(Return&) { }
|
||||
virtual void endVisit(VariableDefinition&) { }
|
||||
virtual void endVisit(Expression&) { }
|
||||
virtual void endVisit(Assignment&) { }
|
||||
virtual void endVisit(UnaryOperation&) { }
|
||||
virtual void endVisit(BinaryOperation&) { }
|
||||
virtual void endVisit(FunctionCall&) { }
|
||||
virtual void endVisit(MemberAccess&) { }
|
||||
virtual void endVisit(IndexAccess&) { }
|
||||
virtual void endVisit(PrimaryExpression&) { }
|
||||
virtual void endVisit(ElementaryTypeNameExpression&) { }
|
||||
virtual void endVisit(Literal&) { }
|
||||
};
|
||||
|
||||
} }
|
52
Parser.cpp
52
Parser.cpp
@ -57,7 +57,8 @@ public:
|
||||
template <class NodeType, typename... Args>
|
||||
ptr<NodeType> createNode(Args&&... _args)
|
||||
{
|
||||
if (m_location.end < 0) markEndPosition();
|
||||
if (m_location.end < 0)
|
||||
markEndPosition();
|
||||
return std::make_shared<NodeType>(m_location, std::forward<Args>(_args)...);
|
||||
}
|
||||
|
||||
@ -82,7 +83,7 @@ ptr<ContractDefinition> Parser::parseContractDefinition()
|
||||
ASTNodeFactory nodeFactory(*this);
|
||||
|
||||
expectToken(Token::CONTRACT);
|
||||
std::string name = expectIdentifier();
|
||||
ptr<ASTString> name = expectIdentifierToken();
|
||||
expectToken(Token::LBRACE);
|
||||
|
||||
vecptr<StructDefinition> structs;
|
||||
@ -111,7 +112,7 @@ ptr<ContractDefinition> Parser::parseContractDefinition()
|
||||
}
|
||||
nodeFactory.markEndPosition();
|
||||
|
||||
m_scanner->next();
|
||||
expectToken(Token::RBRACE);
|
||||
expectToken(Token::EOS);
|
||||
|
||||
return nodeFactory.createNode<ContractDefinition>(name, structs, stateVariables, functions);
|
||||
@ -122,7 +123,7 @@ ptr<FunctionDefinition> Parser::parseFunctionDefinition(bool _isPublic)
|
||||
ASTNodeFactory nodeFactory(*this);
|
||||
|
||||
expectToken(Token::FUNCTION);
|
||||
std::string name(expectIdentifier());
|
||||
ptr<ASTString> name(expectIdentifierToken());
|
||||
ptr<ParameterList> parameters(parseParameterList());
|
||||
bool isDeclaredConst = false;
|
||||
if (m_scanner->getCurrentToken() == Token::CONST) {
|
||||
@ -145,7 +146,7 @@ ptr<StructDefinition> Parser::parseStructDefinition()
|
||||
ASTNodeFactory nodeFactory(*this);
|
||||
|
||||
expectToken(Token::STRUCT);
|
||||
std::string name = expectIdentifier();
|
||||
ptr<ASTString> name = expectIdentifierToken();
|
||||
vecptr<VariableDeclaration> members;
|
||||
expectToken(Token::LBRACE);
|
||||
while (m_scanner->getCurrentToken() != Token::RBRACE) {
|
||||
@ -164,8 +165,7 @@ ptr<VariableDeclaration> Parser::parseVariableDeclaration()
|
||||
|
||||
ptr<TypeName> type = parseTypeName();
|
||||
nodeFactory.markEndPosition();
|
||||
std::string name = expectIdentifier();
|
||||
return nodeFactory.createNode<VariableDeclaration>(type, name);
|
||||
return nodeFactory.createNode<VariableDeclaration>(type, expectIdentifierToken());
|
||||
}
|
||||
|
||||
ptr<TypeName> Parser::parseTypeName()
|
||||
@ -181,8 +181,9 @@ ptr<TypeName> Parser::parseTypeName()
|
||||
} else if (token == Token::MAPPING) {
|
||||
type = parseMapping();
|
||||
} else if (token == Token::IDENTIFIER) {
|
||||
type = ASTNodeFactory(*this).createNode<UserDefinedTypeName>(m_scanner->getCurrentLiteral());
|
||||
m_scanner->next();
|
||||
ASTNodeFactory nodeFactory(*this);
|
||||
nodeFactory.markEndPosition();
|
||||
type = nodeFactory.createNode<UserDefinedTypeName>(expectIdentifierToken());
|
||||
} else {
|
||||
throwExpectationError("Expected type name");
|
||||
}
|
||||
@ -410,8 +411,7 @@ ptr<Expression> Parser::parseLeftHandSideExpression()
|
||||
{
|
||||
m_scanner->next();
|
||||
nodeFactory.markEndPosition();
|
||||
std::string memberName = expectIdentifier();
|
||||
expression = nodeFactory.createNode<MemberAccess>(expression, memberName);
|
||||
expression = nodeFactory.createNode<MemberAccess>(expression, expectIdentifierToken());
|
||||
}
|
||||
break;
|
||||
case Token::LPAREN:
|
||||
@ -431,19 +431,25 @@ ptr<Expression> Parser::parseLeftHandSideExpression()
|
||||
|
||||
ptr<Expression> Parser::parsePrimaryExpression()
|
||||
{
|
||||
ASTNodeFactory nodeFactory(*this);
|
||||
Token::Value token = m_scanner->getCurrentToken();
|
||||
ptr<Expression> expression;
|
||||
|
||||
switch (token) {
|
||||
case Token::TRUE_LITERAL:
|
||||
case Token::FALSE_LITERAL:
|
||||
expression = nodeFactory.createNode<Literal>(token, ptr<ASTString>());
|
||||
m_scanner->next();
|
||||
return ASTNodeFactory(*this).createNode<Literal>(token, std::string());
|
||||
break;
|
||||
case Token::NUMBER:
|
||||
case Token::STRING_LITERAL:
|
||||
m_scanner->next();
|
||||
return ASTNodeFactory(*this).createNode<Literal>(token, m_scanner->getCurrentLiteral());
|
||||
nodeFactory.markEndPosition();
|
||||
expression = nodeFactory.createNode<Literal>(token, getLiteralAndAdvance());
|
||||
break;
|
||||
case Token::IDENTIFIER:
|
||||
m_scanner->next();
|
||||
return ASTNodeFactory(*this).createNode<Identifier>(m_scanner->getCurrentLiteral());
|
||||
nodeFactory.markEndPosition();
|
||||
expression = nodeFactory.createNode<Identifier>(getLiteralAndAdvance());
|
||||
break;
|
||||
case Token::LPAREN:
|
||||
{
|
||||
m_scanner->next();
|
||||
@ -454,13 +460,14 @@ ptr<Expression> Parser::parsePrimaryExpression()
|
||||
default:
|
||||
if (Token::IsElementaryTypeName(token)) {
|
||||
// used for casts
|
||||
expression = nodeFactory.createNode<ElementaryTypeNameExpression>(token);
|
||||
m_scanner->next();
|
||||
return ASTNodeFactory(*this).createNode<ElementaryTypeNameExpression>(token);
|
||||
} else {
|
||||
throwExpectationError("Expected primary expression.");
|
||||
return ptr<Expression>(); // this is not reached
|
||||
}
|
||||
}
|
||||
return expression;
|
||||
}
|
||||
|
||||
vecptr<Expression> Parser::parseFunctionCallArguments()
|
||||
@ -492,14 +499,19 @@ Token::Value Parser::expectAssignmentOperator()
|
||||
return op;
|
||||
}
|
||||
|
||||
std::string Parser::expectIdentifier()
|
||||
ptr<ASTString> Parser::expectIdentifierToken()
|
||||
{
|
||||
if (m_scanner->getCurrentToken() != Token::IDENTIFIER)
|
||||
throwExpectationError("Expected identifier");
|
||||
|
||||
std::string literal = m_scanner->getCurrentLiteral();
|
||||
return getLiteralAndAdvance();
|
||||
}
|
||||
|
||||
ptr<ASTString> Parser::getLiteralAndAdvance()
|
||||
{
|
||||
ptr<ASTString> identifier = std::make_shared<ASTString>(m_scanner->getCurrentLiteral());
|
||||
m_scanner->next();
|
||||
return literal;
|
||||
return identifier;
|
||||
}
|
||||
|
||||
void Parser::throwExpectationError(const std::string& _description)
|
||||
|
3
Parser.h
3
Parser.h
@ -69,7 +69,8 @@ private:
|
||||
/// If current token value is not _value, throw exception otherwise advance token.
|
||||
void expectToken(Token::Value _value);
|
||||
Token::Value expectAssignmentOperator();
|
||||
std::string expectIdentifier();
|
||||
ptr<ASTString> expectIdentifierToken();
|
||||
ptr<ASTString> getLiteralAndAdvance();
|
||||
void throwExpectationError(const std::string& _description);
|
||||
/// @}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user