Christian
10 years ago
11 changed files with 745 additions and 47 deletions
@ -0,0 +1,23 @@ |
|||||
|
/*
|
||||
|
This file is part of cpp-ethereum. |
||||
|
|
||||
|
cpp-ethereum is free software: you can redistribute it and/or modify |
||||
|
it under the terms of the GNU General Public License as published by |
||||
|
the Free Software Foundation, either version 3 of the License, or |
||||
|
(at your option) any later version. |
||||
|
|
||||
|
cpp-ethereum is distributed in the hope that it will be useful, |
||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
GNU General Public License for more details. |
||||
|
|
||||
|
You should have received a copy of the GNU General Public License |
||||
|
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
*/ |
||||
|
/**
|
||||
|
* @author Christian <c@ethdev.com> |
||||
|
* @date 2014 |
||||
|
* Solidity abstract syntax tree. |
||||
|
*/ |
||||
|
|
||||
|
#include <libsolidity/AST.h> |
@ -0,0 +1,287 @@ |
|||||
|
/*
|
||||
|
This file is part of cpp-ethereum. |
||||
|
|
||||
|
cpp-ethereum is free software: you can redistribute it and/or modify |
||||
|
it under the terms of the GNU General Public License as published by |
||||
|
the Free Software Foundation, either version 3 of the License, or |
||||
|
(at your option) any later version. |
||||
|
|
||||
|
cpp-ethereum is distributed in the hope that it will be useful, |
||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
GNU General Public License for more details. |
||||
|
|
||||
|
You should have received a copy of the GNU General Public License |
||||
|
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
*/ |
||||
|
/**
|
||||
|
* @author Christian <c@ethdev.com> |
||||
|
* @date 2014 |
||||
|
* Solidity abstract syntax tree. |
||||
|
*/ |
||||
|
|
||||
|
#pragma once |
||||
|
|
||||
|
#include <string> |
||||
|
#include <vector> |
||||
|
#include <memory> |
||||
|
|
||||
|
#include <libsolidity/BaseTypes.h> |
||||
|
#include <libsolidity/Token.h> |
||||
|
|
||||
|
namespace dev { |
||||
|
namespace solidity { |
||||
|
|
||||
|
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 ASTNode |
||||
|
{ |
||||
|
public: |
||||
|
explicit ASTNode(const Location& _location) |
||||
|
: m_location(_location) |
||||
|
{} |
||||
|
private: |
||||
|
Location m_location; |
||||
|
}; |
||||
|
|
||||
|
class ContractDefinition : public ASTNode |
||||
|
{ |
||||
|
public: |
||||
|
ContractDefinition(const Location& _location, |
||||
|
const std::string& _name, |
||||
|
const vecptr<StructDefinition>& _definedStructs, |
||||
|
const vecptr<VariableDeclaration>& _stateVariables, |
||||
|
const vecptr<FunctionDefinition>& _definedFunctions) |
||||
|
: ASTNode(_location), |
||||
|
m_name(_name), |
||||
|
m_definedStructs(_definedStructs), |
||||
|
m_stateVariables(_stateVariables), |
||||
|
m_definedFunctions(_definedFunctions) |
||||
|
{} |
||||
|
|
||||
|
private: |
||||
|
std::string m_name; |
||||
|
vecptr<StructDefinition> m_definedStructs; |
||||
|
vecptr<VariableDeclaration> m_stateVariables; |
||||
|
vecptr<FunctionDefinition> m_definedFunctions; |
||||
|
}; |
||||
|
|
||||
|
class StructDefinition : public ASTNode |
||||
|
{ |
||||
|
private: |
||||
|
std::string m_name; |
||||
|
vecptr<VariableDeclaration> m_members; |
||||
|
}; |
||||
|
|
||||
|
class FunctionDefinition : public ASTNode |
||||
|
{ |
||||
|
private: |
||||
|
std::string m_name; |
||||
|
vecptr<VariableDeclaration> m_arguments; |
||||
|
bool m_isDeclaredConst; |
||||
|
vecptr<VariableDeclaration> m_returns; |
||||
|
ptr<Block> m_body; |
||||
|
}; |
||||
|
|
||||
|
class VariableDeclaration : public ASTNode |
||||
|
{ |
||||
|
public: |
||||
|
VariableDeclaration(const Location& _location, |
||||
|
const ptr<TypeName>& _type, |
||||
|
const std::string& _name) |
||||
|
: ASTNode(_location), |
||||
|
m_type(_type), |
||||
|
m_name(_name) |
||||
|
{} |
||||
|
private: |
||||
|
ptr<TypeName> m_type; ///<s can be empty ("var")
|
||||
|
std::string m_name; |
||||
|
}; |
||||
|
|
||||
|
/// types
|
||||
|
/// @{
|
||||
|
|
||||
|
class TypeName : public ASTNode |
||||
|
{ |
||||
|
public: |
||||
|
explicit TypeName(const Location& _location) |
||||
|
: ASTNode(_location) |
||||
|
{} |
||||
|
}; |
||||
|
|
||||
|
/// any pre-defined type that is not a mapping
|
||||
|
class ElementaryTypeName : public TypeName |
||||
|
{ |
||||
|
public: |
||||
|
explicit ElementaryTypeName(const Location& _location, Token::Value _type) |
||||
|
: TypeName(_location), m_type(_type) |
||||
|
{} |
||||
|
private: |
||||
|
Token::Value m_type; |
||||
|
}; |
||||
|
|
||||
|
class UserDefinedTypeName : public TypeName |
||||
|
{ |
||||
|
public: |
||||
|
UserDefinedTypeName(const Location& _location, const std::string& _name) |
||||
|
: TypeName(_location), m_name(_name) |
||||
|
{} |
||||
|
private: |
||||
|
std::string m_name; |
||||
|
}; |
||||
|
|
||||
|
class MappingTypeName : public TypeName |
||||
|
{ |
||||
|
public: |
||||
|
explicit MappingTypeName(const Location& _location) |
||||
|
: TypeName(_location) |
||||
|
{} |
||||
|
private: |
||||
|
ptr<ElementaryTypeName> m_keyType; |
||||
|
ptr<TypeName> m_valueType; |
||||
|
}; |
||||
|
|
||||
|
/// @}
|
||||
|
|
||||
|
/// Statements
|
||||
|
/// @{
|
||||
|
|
||||
|
class Statement : public ASTNode |
||||
|
{ |
||||
|
}; |
||||
|
|
||||
|
class Block : public Statement |
||||
|
{ |
||||
|
private: |
||||
|
vecptr<Statement> m_statements; |
||||
|
}; |
||||
|
|
||||
|
class IfStatement : public Statement |
||||
|
{ |
||||
|
|
||||
|
private: |
||||
|
ptr<Expression> m_condition; |
||||
|
ptr<Statement> m_trueBody; |
||||
|
ptr<Statement> m_falseBody; |
||||
|
}; |
||||
|
|
||||
|
class BreakableStatement : public Statement |
||||
|
{ |
||||
|
|
||||
|
}; |
||||
|
|
||||
|
class WhileStatement : public BreakableStatement |
||||
|
{ |
||||
|
private: |
||||
|
ptr<Expression> m_condition; |
||||
|
ptr<Statement> m_body; |
||||
|
}; |
||||
|
|
||||
|
class Continue : public Statement |
||||
|
{ |
||||
|
|
||||
|
}; |
||||
|
|
||||
|
class Break : public Statement |
||||
|
{ |
||||
|
|
||||
|
}; |
||||
|
|
||||
|
class Return : public Statement |
||||
|
{ |
||||
|
private: |
||||
|
ptr<Expression> m_expression; |
||||
|
}; |
||||
|
|
||||
|
class VariableAssignment : public Statement |
||||
|
{ |
||||
|
private: |
||||
|
ptr<VariableDeclaration> m_variable; |
||||
|
Token::Value m_assigmentOperator; |
||||
|
ptr<Expression> m_rightHandSide; ///< can be missing
|
||||
|
}; |
||||
|
|
||||
|
class Expression : public Statement |
||||
|
{ |
||||
|
private: |
||||
|
}; |
||||
|
|
||||
|
/// @}
|
||||
|
|
||||
|
/// Expressions
|
||||
|
/// @{
|
||||
|
|
||||
|
class Assignment : public Expression |
||||
|
{ |
||||
|
private: |
||||
|
ptr<Expression> m_leftHandSide; |
||||
|
Token::Value m_assigmentOperator; |
||||
|
ptr<Expression> m_rightHandSide; |
||||
|
}; |
||||
|
|
||||
|
class UnaryOperation : public Expression |
||||
|
{ |
||||
|
private: |
||||
|
Token::Value m_operator; |
||||
|
ptr<Expression> m_subExpression; |
||||
|
bool isPrefix; |
||||
|
}; |
||||
|
|
||||
|
class BinaryOperation : public Expression |
||||
|
{ |
||||
|
private: |
||||
|
ptr<Expression> m_left; |
||||
|
ptr<Expression> m_right; |
||||
|
Token::Value m_operator; |
||||
|
}; |
||||
|
|
||||
|
class FunctionCall : public Expression |
||||
|
{ |
||||
|
private: |
||||
|
std::string m_functionName; // TODO only calls to fixed, named functions for now
|
||||
|
vecptr<Expression> m_arguments; |
||||
|
}; |
||||
|
|
||||
|
class MemberAccess : public Expression |
||||
|
{ |
||||
|
private: |
||||
|
ptr<Expression> m_expression; |
||||
|
std::string m_memberName; |
||||
|
}; |
||||
|
|
||||
|
class IndexAccess : public Expression |
||||
|
{ |
||||
|
ptr<Expression> m_base; |
||||
|
ptr<Expression> m_index; |
||||
|
}; |
||||
|
|
||||
|
class PrimaryExpression : public Expression |
||||
|
{ |
||||
|
}; |
||||
|
|
||||
|
class Identifier : public PrimaryExpression |
||||
|
{ |
||||
|
private: |
||||
|
std::string m_name; |
||||
|
}; |
||||
|
|
||||
|
class Literal : public PrimaryExpression |
||||
|
{ |
||||
|
private: |
||||
|
std::string m_value; |
||||
|
}; |
||||
|
|
||||
|
/// @}
|
||||
|
|
||||
|
|
||||
|
} } |
@ -0,0 +1,22 @@ |
|||||
|
#pragma once |
||||
|
|
||||
|
|
||||
|
namespace dev { |
||||
|
namespace solidity { |
||||
|
|
||||
|
// Representation of an interval of source positions.
|
||||
|
struct Location { |
||||
|
Location(int b, int e) : beg_pos(b), end_pos(e) { } |
||||
|
Location() : beg_pos(0), end_pos(0) { } |
||||
|
|
||||
|
bool IsValid() const { |
||||
|
return beg_pos >= 0 && end_pos >= beg_pos; |
||||
|
} |
||||
|
|
||||
|
static Location invalid() { return Location(-1, -1); } |
||||
|
|
||||
|
int beg_pos; |
||||
|
int end_pos; |
||||
|
}; |
||||
|
|
||||
|
} } |
@ -0,0 +1,180 @@ |
|||||
|
/*
|
||||
|
This file is part of cpp-ethereum. |
||||
|
|
||||
|
cpp-ethereum is free software: you can redistribute it and/or modify |
||||
|
it under the terms of the GNU General Public License as published by |
||||
|
the Free Software Foundation, either version 3 of the License, or |
||||
|
(at your option) any later version. |
||||
|
|
||||
|
cpp-ethereum is distributed in the hope that it will be useful, |
||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
GNU General Public License for more details. |
||||
|
|
||||
|
You should have received a copy of the GNU General Public License |
||||
|
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
*/ |
||||
|
/**
|
||||
|
* @author Christian <c@ethdev.com> |
||||
|
* @date 2014 |
||||
|
* Solidity parser. |
||||
|
*/ |
||||
|
|
||||
|
#include "libsolidity/BaseTypes.h" |
||||
|
#include "libsolidity/Parser.h" |
||||
|
#include "libsolidity/Scanner.h" |
||||
|
|
||||
|
namespace dev { |
||||
|
namespace solidity { |
||||
|
|
||||
|
ptr<ASTNode> Parser::parse(Scanner& _scanner) |
||||
|
{ |
||||
|
m_scanner = &_scanner; |
||||
|
|
||||
|
return parseContractDefinition(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/// AST node factory that also tracks the begin and end position of an AST node
|
||||
|
/// while it is being parsed
|
||||
|
class Parser::ASTNodeFactory |
||||
|
{ |
||||
|
public: |
||||
|
ASTNodeFactory(const Parser& _parser) |
||||
|
: m_parser(_parser), |
||||
|
m_location(_parser.getPosition(), -1) |
||||
|
{} |
||||
|
|
||||
|
void markEndPosition() |
||||
|
{ |
||||
|
m_location.end_pos = m_parser.getEndPosition(); |
||||
|
} |
||||
|
|
||||
|
/// @todo: check that this actually uses perfect forwarding
|
||||
|
template <class NodeType, typename... Args> |
||||
|
ptr<NodeType> createNode(Args&&... _args) |
||||
|
{ |
||||
|
if (m_location.end_pos < 0) markEndPosition(); |
||||
|
return std::make_shared<NodeType>(m_location, std::forward<Args>(_args)...); |
||||
|
} |
||||
|
|
||||
|
private: |
||||
|
const Parser& m_parser; |
||||
|
Location m_location; |
||||
|
}; |
||||
|
|
||||
|
int Parser::getPosition() const |
||||
|
{ |
||||
|
return m_scanner->getCurrentLocation().beg_pos; |
||||
|
} |
||||
|
|
||||
|
int Parser::getEndPosition() const |
||||
|
{ |
||||
|
return m_scanner->getCurrentLocation().end_pos; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
ptr<ContractDefinition> Parser::parseContractDefinition() |
||||
|
{ |
||||
|
ASTNodeFactory nodeFactory(*this); |
||||
|
|
||||
|
expectToken(Token::CONTRACT); |
||||
|
std::string name = expectIdentifier(); |
||||
|
expectToken(Token::LBRACE); |
||||
|
|
||||
|
vecptr<StructDefinition> structs; |
||||
|
vecptr<VariableDeclaration> stateVariables; |
||||
|
vecptr<FunctionDefinition> functions; |
||||
|
bool visibilityIsPublic = true; |
||||
|
while (true) { |
||||
|
Token::Value currentToken = m_scanner->getCurrentToken(); |
||||
|
if (currentToken == Token::RBRACE) { |
||||
|
break; |
||||
|
} else if (currentToken == Token::PUBLIC || currentToken == Token::PRIVATE) { |
||||
|
visibilityIsPublic = (m_scanner->getCurrentToken() == Token::PUBLIC); |
||||
|
m_scanner->next(); |
||||
|
expectToken(Token::COLON); |
||||
|
} else if (currentToken == Token::FUNCTION) { |
||||
|
functions.push_back(parseFunctionDefinition(visibilityIsPublic)); |
||||
|
} else if (currentToken == Token::STRUCT) { |
||||
|
structs.push_back(parseStructDefinition()); |
||||
|
expectToken(Token::SEMICOLON); |
||||
|
} else if (currentToken == Token::IDENTIFIER || currentToken == Token::MAPPING || |
||||
|
Token::IsElementaryTypeName(currentToken)) { |
||||
|
stateVariables.push_back(parseVariableDeclaration()); |
||||
|
expectToken(Token::SEMICOLON); |
||||
|
} else { |
||||
|
throwExpectationError("Function, variable or struct declaration expected."); |
||||
|
} |
||||
|
} |
||||
|
nodeFactory.markEndPosition(); |
||||
|
|
||||
|
m_scanner->next(); |
||||
|
expectToken(Token::EOS); |
||||
|
|
||||
|
return nodeFactory.createNode<ContractDefinition>(name, structs, stateVariables, functions); |
||||
|
} |
||||
|
|
||||
|
ptr<FunctionDefinition> Parser::parseFunctionDefinition(bool _isPublic) |
||||
|
{ |
||||
|
(void) _isPublic; |
||||
|
throwExpectationError("Function parsing is not yet implemented."); |
||||
|
} |
||||
|
|
||||
|
ptr<StructDefinition> Parser::parseStructDefinition() |
||||
|
{ |
||||
|
throwExpectationError("Struct definition parsing is not yet implemented."); |
||||
|
} |
||||
|
|
||||
|
ptr<VariableDeclaration> Parser::parseVariableDeclaration() |
||||
|
{ |
||||
|
ASTNodeFactory nodeFactory(*this); |
||||
|
|
||||
|
ptr<TypeName> type; |
||||
|
Token::Value token = m_scanner->getCurrentToken(); |
||||
|
if (Token::IsElementaryTypeName(token)) { |
||||
|
type = ASTNodeFactory(*this).createNode<ElementaryTypeName>(token); |
||||
|
m_scanner->next(); |
||||
|
} else if (token == Token::VAR) { |
||||
|
type = ASTNodeFactory(*this).createNode<TypeName>(); |
||||
|
m_scanner->next(); |
||||
|
} else if (token == Token::MAPPING) { |
||||
|
// TODO
|
||||
|
throwExpectationError("mappings are not yet implemented"); |
||||
|
} else if (token == Token::IDENTIFIER) { |
||||
|
type = ASTNodeFactory(*this).createNode<UserDefinedTypeName>(m_scanner->getCurrentLiteral()); |
||||
|
m_scanner->next(); |
||||
|
} else { |
||||
|
throwExpectationError("Expected variable declaration"); |
||||
|
} |
||||
|
nodeFactory.markEndPosition(); |
||||
|
std::string name = expectIdentifier(); |
||||
|
return nodeFactory.createNode<VariableDeclaration>(type, name); |
||||
|
} |
||||
|
|
||||
|
void Parser::expectToken(Token::Value _value) |
||||
|
{ |
||||
|
if (m_scanner->getCurrentToken() != _value) |
||||
|
throwExpectationError(std::string("Expected token ") + std::string(Token::Name(_value))); |
||||
|
m_scanner->next(); |
||||
|
} |
||||
|
|
||||
|
std::string Parser::expectIdentifier() |
||||
|
{ |
||||
|
if (m_scanner->getCurrentToken() != Token::IDENTIFIER) |
||||
|
throwExpectationError("Expected identifier"); |
||||
|
|
||||
|
std::string literal = m_scanner->getCurrentLiteral(); |
||||
|
m_scanner->next(); |
||||
|
return literal; |
||||
|
} |
||||
|
|
||||
|
void Parser::throwExpectationError(const std::string& _description) |
||||
|
{ |
||||
|
(void) _description; |
||||
|
/// @todo make a proper exception hierarchy
|
||||
|
throw std::exception();//_description);
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
} } |
@ -0,0 +1,64 @@ |
|||||
|
/*
|
||||
|
This file is part of cpp-ethereum. |
||||
|
|
||||
|
cpp-ethereum is free software: you can redistribute it and/or modify |
||||
|
it under the terms of the GNU General Public License as published by |
||||
|
the Free Software Foundation, either version 3 of the License, or |
||||
|
(at your option) any later version. |
||||
|
|
||||
|
cpp-ethereum is distributed in the hope that it will be useful, |
||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
GNU General Public License for more details. |
||||
|
|
||||
|
You should have received a copy of the GNU General Public License |
||||
|
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
*/ |
||||
|
/**
|
||||
|
* @author Christian <c@ethdev.com> |
||||
|
* @date 2014 |
||||
|
* Solidity parser. |
||||
|
*/ |
||||
|
|
||||
|
#pragma once |
||||
|
|
||||
|
#include "libsolidity/AST.h" |
||||
|
|
||||
|
namespace dev { |
||||
|
namespace solidity { |
||||
|
|
||||
|
class Scanner; |
||||
|
|
||||
|
class Parser |
||||
|
{ |
||||
|
public: |
||||
|
ptr<ASTNode> parse(Scanner& _scanner); |
||||
|
|
||||
|
private: |
||||
|
class ASTNodeFactory; |
||||
|
|
||||
|
/// Start position of the current token
|
||||
|
int getPosition() const; |
||||
|
/// End position of the current token
|
||||
|
int getEndPosition() const; |
||||
|
|
||||
|
/// Parsing functions for the AST nodes
|
||||
|
/// @{
|
||||
|
ptr<ContractDefinition> parseContractDefinition(); |
||||
|
ptr<FunctionDefinition> parseFunctionDefinition(bool _isPublic); |
||||
|
ptr<StructDefinition> parseStructDefinition(); |
||||
|
ptr<VariableDeclaration> parseVariableDeclaration(); |
||||
|
/// @}
|
||||
|
|
||||
|
/// Helper functions
|
||||
|
/// @{
|
||||
|
/// If current token value is not _value, throw exception otherwise advance token.
|
||||
|
void expectToken(Token::Value _value); |
||||
|
std::string expectIdentifier(); |
||||
|
void throwExpectationError(const std::string& _description); |
||||
|
/// @}
|
||||
|
|
||||
|
Scanner* m_scanner; |
||||
|
}; |
||||
|
|
||||
|
} } |
@ -0,0 +1,32 @@ |
|||||
|
ContractDefinition = 'contract' Identifier '{' ContractPart* '}' |
||||
|
ContractPart = VariableDeclaration ';' | StructDefinition ';' | |
||||
|
FunctionDefinition ';' | 'public:' | 'private:' |
||||
|
|
||||
|
StructDefinition = 'struct' Identifier '{' |
||||
|
( VariableDeclaration (';' VariableDeclaration)* )? '} |
||||
|
|
||||
|
FunctionDefinition = 'function' Identifier ArgumentList 'const'? |
||||
|
'returns' ArgumentList Block |
||||
|
ArgumentList = '(' ( VariableDeclaration (',' VariableDeclaration)* )? ')' |
||||
|
// semantic restriction: mappings and structs (recursively) containing mappings |
||||
|
// are not allowed in argument lists |
||||
|
VariableDeclaration = TypeName Identifier |
||||
|
TypeName = PredefinedType | Identifier | MappingType |
||||
|
MappingType = 'mapping' '(' SimplePredefinedType '=>' TypeName ')' |
||||
|
|
||||
|
Block = '{' Statement* '}' |
||||
|
Statement = IfStatement | WhileStatement | Continue | Break | Return | VariableAssignment | Expression ';' | Block |
||||
|
|
||||
|
IfStatement = 'if' '(' Expression ')' Statement ( 'else' Statement )? |
||||
|
WhileStatement = 'while' '(' Expression ')' Statement |
||||
|
Continue = 'continue' ';' |
||||
|
Break = 'break' ';' |
||||
|
Return = 'return' Expression? ';' |
||||
|
VariableAssignment = VariableDeclaration ( AssignmentOp Expression )? ';' |
||||
|
|
||||
|
Expression = Assignment | UnaryOperation | BinaryOperation | FunctionCall | IndexAccess | MemberAccess | PrimaryExpression |
||||
|
Assignment = Expression (AssignmentOp Expression) |
||||
|
FunctionCall = Identifier '(' ( Expression ( ',' Expression )* ) ')' |
||||
|
MemberAccess = Expression '.' Identifier |
||||
|
IndexAccess = Expression '[' Expresison ']' |
||||
|
PrimaryExpression = Identifier | NumberLiteral | StringLiteral | '(' Expression ')' |
@ -0,0 +1,52 @@ |
|||||
|
/*
|
||||
|
This file is part of cpp-ethereum. |
||||
|
|
||||
|
cpp-ethereum is free software: you can redistribute it and/or modify |
||||
|
it under the terms of the GNU General Public License as published by |
||||
|
the Free Software Foundation, either version 3 of the License, or |
||||
|
(at your option) any later version. |
||||
|
|
||||
|
cpp-ethereum is distributed in the hope that it will be useful, |
||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
GNU General Public License for more details. |
||||
|
|
||||
|
You should have received a copy of the GNU General Public License |
||||
|
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
*/ |
||||
|
/**
|
||||
|
* @author Christian <c@ethdev.com> |
||||
|
* @date 2014 |
||||
|
* Unit tests for the solidity parser. |
||||
|
*/ |
||||
|
|
||||
|
#include <string> |
||||
|
|
||||
|
#include <libsolidity/Scanner.h> |
||||
|
#include <libsolidity/Parser.h> |
||||
|
#include <boost/test/unit_test.hpp> |
||||
|
|
||||
|
namespace dev { |
||||
|
namespace solidity { |
||||
|
namespace test { |
||||
|
|
||||
|
BOOST_AUTO_TEST_SUITE(SolidityParser) |
||||
|
|
||||
|
BOOST_AUTO_TEST_CASE(smoke_test) |
||||
|
{ |
||||
|
std::string text = "contract test123 {\n" |
||||
|
"\tuint256 stateVariable1;\n" |
||||
|
"}\n"; |
||||
|
Parser parser; |
||||
|
CharStream str(text); |
||||
|
// @todo: figure out why this does not compile
|
||||
|
//Scanner scanner(CharStream(text));
|
||||
|
Scanner scanner(str); |
||||
|
BOOST_CHECK_NO_THROW(parser.parse(scanner)); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
BOOST_AUTO_TEST_SUITE_END() |
||||
|
|
||||
|
} } } // end namespaces
|
||||
|
|
Loading…
Reference in new issue