libeval_compiler: integrated in common/
This commit is contained in:
parent
539984229d
commit
aaa91655aa
|
@ -4,7 +4,7 @@ if( COMPILER_SUPPORTS_WARNINGS )
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARN_FLAGS_C}")
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARN_FLAGS_C}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_subdirectory( libeval )
|
add_subdirectory( libeval libeval_compiler )
|
||||||
|
|
||||||
include_directories( BEFORE ${INC_BEFORE} )
|
include_directories( BEFORE ${INC_BEFORE} )
|
||||||
include_directories(
|
include_directories(
|
||||||
|
@ -409,6 +409,7 @@ set( COMMON_SRCS
|
||||||
project/project_local_settings.cpp
|
project/project_local_settings.cpp
|
||||||
|
|
||||||
libeval/numeric_evaluator.cpp
|
libeval/numeric_evaluator.cpp
|
||||||
|
libeval_compiler/libeval_compiler.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
add_library( common STATIC
|
add_library( common STATIC
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
#line 33 "grammar.lemon"
|
#line 33 "grammar.lemon"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include "libeval_compiler.h"
|
#include <libeval_compiler/libeval_compiler.h>
|
||||||
#line 33 "grammar.c"
|
#line 33 "grammar.c"
|
||||||
/**************** End of %include directives **********************************/
|
/**************** End of %include directives **********************************/
|
||||||
/* These constants specify the various numeric values for terminal symbols
|
/* These constants specify the various numeric values for terminal symbols
|
|
@ -32,7 +32,7 @@
|
||||||
|
|
||||||
%include {
|
%include {
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include "libeval_compiler.h"
|
#include <libeval_compiler/libeval_compiler.h>
|
||||||
}
|
}
|
||||||
|
|
||||||
%syntax_error {
|
%syntax_error {
|
|
@ -24,7 +24,7 @@
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "libeval_compiler.h"
|
#include <libeval_compiler/libeval_compiler.h>
|
||||||
|
|
||||||
/* The (generated) lemon parser is written in C.
|
/* The (generated) lemon parser is written in C.
|
||||||
* In order to keep its symbol from the global namespace include the parser code with
|
* In order to keep its symbol from the global namespace include the parser code with
|
||||||
|
@ -46,14 +46,17 @@ namespace LIBEVAL
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void libeval_dbg( const char* fmt, ... )
|
static void libeval_dbg( int level, const char* fmt, ... )
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
if(level <= 10) // fixme: tom's debugging.
|
||||||
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start( ap, fmt );
|
va_start( ap, fmt );
|
||||||
fprintf( stderr, "libeval: " );
|
fprintf( stderr, "libeval: " );
|
||||||
vfprintf( stderr, fmt, ap );
|
vfprintf( stderr, fmt, ap );
|
||||||
va_end( ap );
|
va_end( ap );
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,8 +149,8 @@ bool TOKENIZER::MatchAhead( std::string match, std::function<bool( int )> stopCo
|
||||||
|
|
||||||
COMPILER::COMPILER()
|
COMPILER::COMPILER()
|
||||||
{
|
{
|
||||||
|
m_errorStatus.pendingError = false;
|
||||||
m_localeDecimalSeparator = '.';
|
m_localeDecimalSeparator = '.';
|
||||||
m_parseError = false;
|
|
||||||
m_parseFinished = false;
|
m_parseFinished = false;
|
||||||
m_unitResolver.reset( new UNIT_RESOLVER );
|
m_unitResolver.reset( new UNIT_RESOLVER );
|
||||||
m_parser = LIBEVAL::ParseAlloc( malloc );
|
m_parser = LIBEVAL::ParseAlloc( malloc );
|
||||||
|
@ -169,13 +172,15 @@ void COMPILER::Clear()
|
||||||
{
|
{
|
||||||
//free( current.token );
|
//free( current.token );
|
||||||
m_tokenizer.Clear();
|
m_tokenizer.Clear();
|
||||||
m_parseError = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void COMPILER::parseError( const char* s )
|
void COMPILER::parseError( const char* s )
|
||||||
{
|
{
|
||||||
m_parseError = true;
|
libeval_dbg(0, "PARSE ERROR: %s\n", s );
|
||||||
|
m_errorStatus.pendingError = true;
|
||||||
|
m_errorStatus.message = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -189,13 +194,14 @@ bool COMPILER::Compile( const std::string& aString, UCODE* aCode )
|
||||||
{
|
{
|
||||||
// Feed parser token after token until end of input.
|
// Feed parser token after token until end of input.
|
||||||
|
|
||||||
|
|
||||||
newString( aString );
|
newString( aString );
|
||||||
|
m_errorStatus.pendingError = false;
|
||||||
m_tree = nullptr;
|
m_tree = nullptr;
|
||||||
m_parseError = false;
|
|
||||||
m_parseFinished = false;
|
m_parseFinished = false;
|
||||||
T_TOKEN tok;
|
T_TOKEN tok;
|
||||||
|
|
||||||
libeval_dbg( "str: '%s' empty: %d\n", aString.c_str(), !!aString.empty() );
|
libeval_dbg(0, "str: '%s' empty: %d\n", aString.c_str(), !!aString.empty() );
|
||||||
|
|
||||||
if( aString.empty() )
|
if( aString.empty() )
|
||||||
{
|
{
|
||||||
|
@ -206,14 +212,15 @@ bool COMPILER::Compile( const std::string& aString, UCODE* aCode )
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
tok = getToken();
|
tok = getToken();
|
||||||
libeval_dbg( "parse: tok %d\n", tok.token );
|
libeval_dbg(10, "parse: tok %d\n", tok.token );
|
||||||
Parse( m_parser, tok.token, tok.value, this );
|
Parse( m_parser, tok.token, tok.value, this );
|
||||||
//printf('error')
|
|
||||||
if( m_parseError )
|
if( m_errorStatus.pendingError )
|
||||||
{
|
{
|
||||||
//printf( "PARSE ERR\n" );
|
m_errorStatus.stage = ERROR_STATUS::CST_PARSE;
|
||||||
m_parseErrorToken = "";
|
m_errorStatus.failingPosition = m_tokenizer.GetPos();
|
||||||
m_parseErrorPos = m_tokenizer.GetPos();
|
m_errorStatus.failingObject = tok.value.value.str;
|
||||||
|
m_errorStatus.message = "Parse error";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,7 +289,7 @@ int COMPILER::resolveUnits()
|
||||||
{
|
{
|
||||||
if( m_tokenizer.MatchAhead( unitName, []( int c ) -> bool { return !isalnum( c ); } ) )
|
if( m_tokenizer.MatchAhead( unitName, []( int c ) -> bool { return !isalnum( c ); } ) )
|
||||||
{
|
{
|
||||||
libeval_dbg( "Match unit '%s'\n", unitName.c_str() );
|
libeval_dbg(10, "Match unit '%s'\n", unitName.c_str() );
|
||||||
m_tokenizer.NextChar( unitName.length() );
|
m_tokenizer.NextChar( unitName.length() );
|
||||||
return unitId;
|
return unitId;
|
||||||
}
|
}
|
||||||
|
@ -356,7 +363,7 @@ bool COMPILER::lexDefault( COMPILER::T_TOKEN& aToken )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
libeval_dbg( "LEX ch '%c' pos %d\n", ch, m_tokenizer.GetPos() );
|
libeval_dbg(10, "LEX ch '%c' pos %d\n", ch, m_tokenizer.GetPos() );
|
||||||
|
|
||||||
if( ch == 0 )
|
if( ch == 0 )
|
||||||
{
|
{
|
||||||
|
@ -466,7 +473,10 @@ bool COMPILER::lexDefault( COMPILER::T_TOKEN& aToken )
|
||||||
retval.token = G_STRUCT_REF;
|
retval.token = G_STRUCT_REF;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
m_parseError = true;
|
m_errorStatus.stage = ERROR_STATUS::CST_PARSE;
|
||||||
|
m_errorStatus.failingPosition = m_tokenizer.GetPos();
|
||||||
|
m_errorStatus.failingObject = ch;
|
||||||
|
m_errorStatus.message = "Syntax error";
|
||||||
break; /* invalid character */
|
break; /* invalid character */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -538,6 +548,12 @@ void dumpNode( std::string& buf, TREE_NODE* tok, int depth = 0 )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ERROR_STATUS COMPILER::GetErrorStatus()
|
||||||
|
{
|
||||||
|
ERROR_STATUS dummy;
|
||||||
|
return dummy;
|
||||||
|
}
|
||||||
|
|
||||||
void COMPILER::setRoot( TREE_NODE root )
|
void COMPILER::setRoot( TREE_NODE root )
|
||||||
{
|
{
|
||||||
m_tree = copyNode( root );
|
m_tree = copyNode( root );
|
||||||
|
@ -576,7 +592,7 @@ bool COMPILER::generateUCode( UCODE* aCode )
|
||||||
assert( node->leaf[0]->op == TR_IDENTIFIER );
|
assert( node->leaf[0]->op == TR_IDENTIFIER );
|
||||||
assert( node->leaf[1]->op == TR_IDENTIFIER );
|
assert( node->leaf[1]->op == TR_IDENTIFIER );
|
||||||
|
|
||||||
auto vref = aCode->createVarRef( node->leaf[0]->value.str, node->leaf[1]->value.str );
|
auto vref = aCode->createVarRef( this, node->leaf[0]->value.str, node->leaf[1]->value.str );
|
||||||
aCode->AddOp( TR_UOP_PUSH_VAR, vref );
|
aCode->AddOp( TR_UOP_PUSH_VAR, vref );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -732,4 +748,20 @@ VALUE* UCODE::Run()
|
||||||
return ctx.Pop();
|
return ctx.Pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UCODE::RuntimeError( const std::string aErrorMsg )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ERROR_STATUS::Format() const
|
||||||
|
{
|
||||||
|
if( !pendingError )
|
||||||
|
return "";
|
||||||
|
|
||||||
|
char str[1024];
|
||||||
|
sprintf(str,"%s (pos: %d, near: '%s')", message.c_str(), failingPosition, failingObject.c_str() );
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace LIBEVAL
|
} // namespace LIBEVAL
|
|
@ -52,6 +52,8 @@
|
||||||
namespace LIBEVAL
|
namespace LIBEVAL
|
||||||
{
|
{
|
||||||
|
|
||||||
|
class COMPILER;
|
||||||
|
|
||||||
struct ERROR_STATUS
|
struct ERROR_STATUS
|
||||||
{
|
{
|
||||||
bool pendingError;
|
bool pendingError;
|
||||||
|
@ -62,9 +64,12 @@ struct ERROR_STATUS
|
||||||
CST_RUNTIME
|
CST_RUNTIME
|
||||||
};
|
};
|
||||||
|
|
||||||
|
STAGE stage;
|
||||||
std::string message;
|
std::string message;
|
||||||
std::string failingObject;
|
std::string failingObject;
|
||||||
int failingPosition;
|
int failingPosition;
|
||||||
|
|
||||||
|
std::string Format() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -230,6 +235,15 @@ private:
|
||||||
std::string m_valueStr;
|
std::string m_valueStr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class UCODE;
|
||||||
|
|
||||||
|
class VAR_REF
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual VAR_TYPE_T GetType( UCODE* aUcode ) = 0;
|
||||||
|
virtual VALUE GetValue( UCODE* aUcode ) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
class UCODE
|
class UCODE
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -289,14 +303,6 @@ public:
|
||||||
void *m_arg;
|
void *m_arg;
|
||||||
};
|
};
|
||||||
|
|
||||||
class VAR_REF
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual VAR_TYPE_T GetType( const UCODE* aUcode ) const = 0;
|
|
||||||
virtual VALUE GetValue( const UCODE* aUcode ) const = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
void AddOp( int op, double value )
|
void AddOp( int op, double value )
|
||||||
{
|
{
|
||||||
auto uop = new UOP( op, new VALUE( value ) );
|
auto uop = new UOP( op, new VALUE( value ) );
|
||||||
|
@ -317,10 +323,11 @@ public:
|
||||||
|
|
||||||
VALUE* Run();
|
VALUE* Run();
|
||||||
std::string Dump() const;
|
std::string Dump() const;
|
||||||
|
void RuntimeError( const std::string aErrorMsg );
|
||||||
|
|
||||||
virtual VAR_REF* createVarRef( const std::string& var, const std::string& field )
|
virtual VAR_REF* createVarRef( COMPILER* aCompiler, const std::string& var, const std::string& field )
|
||||||
{
|
{
|
||||||
return NULL;
|
return nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -392,28 +399,15 @@ public:
|
||||||
/* Check if previous invokation of process() was successful */
|
/* Check if previous invokation of process() was successful */
|
||||||
inline bool IsValid() const
|
inline bool IsValid() const
|
||||||
{
|
{
|
||||||
return !m_parseError;
|
return !m_errorStatus.pendingError;
|
||||||
}
|
|
||||||
|
|
||||||
const std::string GetParseErrorToken() const
|
|
||||||
{
|
|
||||||
return m_parseErrorToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string GetParseErrorMessage() const
|
|
||||||
{
|
|
||||||
return m_parseErrorMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
int GetParseErrorPosition() const
|
|
||||||
{
|
|
||||||
return m_parseErrorPos;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void setRoot( LIBEVAL::TREE_NODE root );
|
void setRoot( LIBEVAL::TREE_NODE root );
|
||||||
|
|
||||||
bool Compile( const std::string& aString, UCODE* aCode );
|
bool Compile( const std::string& aString, UCODE* aCode );
|
||||||
std::string DumpTree();
|
std::string DumpTree();
|
||||||
|
void ReportError( const std::string aErrorMsg );
|
||||||
|
ERROR_STATUS GetErrorStatus();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
enum LEXER_STATE
|
enum LEXER_STATE
|
||||||
|
@ -461,6 +455,7 @@ protected:
|
||||||
int m_parseErrorPos;
|
int m_parseErrorPos;
|
||||||
|
|
||||||
std::unique_ptr<UNIT_RESOLVER> m_unitResolver;
|
std::unique_ptr<UNIT_RESOLVER> m_unitResolver;
|
||||||
|
ERROR_STATUS m_errorStatus;
|
||||||
|
|
||||||
TREE_NODE* m_tree;
|
TREE_NODE* m_tree;
|
||||||
};
|
};
|
Loading…
Reference in New Issue