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}")
|
||||
endif()
|
||||
|
||||
add_subdirectory( libeval )
|
||||
add_subdirectory( libeval libeval_compiler )
|
||||
|
||||
include_directories( BEFORE ${INC_BEFORE} )
|
||||
include_directories(
|
||||
|
@ -409,6 +409,7 @@ set( COMMON_SRCS
|
|||
project/project_local_settings.cpp
|
||||
|
||||
libeval/numeric_evaluator.cpp
|
||||
libeval_compiler/libeval_compiler.cpp
|
||||
)
|
||||
|
||||
add_library( common STATIC
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#line 33 "grammar.lemon"
|
||||
|
||||
#include <assert.h>
|
||||
#include "libeval_compiler.h"
|
||||
#include <libeval_compiler/libeval_compiler.h>
|
||||
#line 33 "grammar.c"
|
||||
/**************** End of %include directives **********************************/
|
||||
/* These constants specify the various numeric values for terminal symbols
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
%include {
|
||||
#include <assert.h>
|
||||
#include "libeval_compiler.h"
|
||||
#include <libeval_compiler/libeval_compiler.h>
|
||||
}
|
||||
|
||||
%syntax_error {
|
|
@ -24,7 +24,7 @@
|
|||
#include <stdarg.h>
|
||||
#endif
|
||||
|
||||
#include "libeval_compiler.h"
|
||||
#include <libeval_compiler/libeval_compiler.h>
|
||||
|
||||
/* The (generated) lemon parser is written in C.
|
||||
* 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
|
||||
#endif
|
||||
|
||||
static void libeval_dbg( const char* fmt, ... )
|
||||
static void libeval_dbg( int level, const char* fmt, ... )
|
||||
{
|
||||
#ifdef DEBUG
|
||||
va_list ap;
|
||||
va_start( ap, fmt );
|
||||
fprintf( stderr, "libeval: " );
|
||||
vfprintf( stderr, fmt, ap );
|
||||
va_end( ap );
|
||||
if(level <= 10) // fixme: tom's debugging.
|
||||
{
|
||||
va_list ap;
|
||||
va_start( ap, fmt );
|
||||
fprintf( stderr, "libeval: " );
|
||||
vfprintf( stderr, fmt, ap );
|
||||
va_end( ap );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -146,8 +149,8 @@ bool TOKENIZER::MatchAhead( std::string match, std::function<bool( int )> stopCo
|
|||
|
||||
COMPILER::COMPILER()
|
||||
{
|
||||
m_errorStatus.pendingError = false;
|
||||
m_localeDecimalSeparator = '.';
|
||||
m_parseError = false;
|
||||
m_parseFinished = false;
|
||||
m_unitResolver.reset( new UNIT_RESOLVER );
|
||||
m_parser = LIBEVAL::ParseAlloc( malloc );
|
||||
|
@ -169,13 +172,15 @@ void COMPILER::Clear()
|
|||
{
|
||||
//free( current.token );
|
||||
m_tokenizer.Clear();
|
||||
m_parseError = true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
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.
|
||||
|
||||
|
||||
newString( aString );
|
||||
m_errorStatus.pendingError = false;
|
||||
m_tree = nullptr;
|
||||
m_parseError = false;
|
||||
m_parseFinished = false;
|
||||
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() )
|
||||
{
|
||||
|
@ -206,14 +212,15 @@ bool COMPILER::Compile( const std::string& aString, UCODE* aCode )
|
|||
do
|
||||
{
|
||||
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 );
|
||||
//printf('error')
|
||||
if( m_parseError )
|
||||
|
||||
if( m_errorStatus.pendingError )
|
||||
{
|
||||
//printf( "PARSE ERR\n" );
|
||||
m_parseErrorToken = "";
|
||||
m_parseErrorPos = m_tokenizer.GetPos();
|
||||
m_errorStatus.stage = ERROR_STATUS::CST_PARSE;
|
||||
m_errorStatus.failingPosition = m_tokenizer.GetPos();
|
||||
m_errorStatus.failingObject = tok.value.value.str;
|
||||
m_errorStatus.message = "Parse error";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -282,7 +289,7 @@ int COMPILER::resolveUnits()
|
|||
{
|
||||
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() );
|
||||
return unitId;
|
||||
}
|
||||
|
@ -356,7 +363,7 @@ bool COMPILER::lexDefault( COMPILER::T_TOKEN& aToken )
|
|||
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 )
|
||||
{
|
||||
|
@ -466,7 +473,10 @@ bool COMPILER::lexDefault( COMPILER::T_TOKEN& aToken )
|
|||
retval.token = G_STRUCT_REF;
|
||||
break;
|
||||
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 */
|
||||
}
|
||||
|
||||
|
@ -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 )
|
||||
{
|
||||
m_tree = copyNode( root );
|
||||
|
@ -576,7 +592,7 @@ bool COMPILER::generateUCode( UCODE* aCode )
|
|||
assert( node->leaf[0]->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 );
|
||||
break;
|
||||
}
|
||||
|
@ -732,4 +748,20 @@ VALUE* UCODE::Run()
|
|||
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
|
|
@ -52,6 +52,8 @@
|
|||
namespace LIBEVAL
|
||||
{
|
||||
|
||||
class COMPILER;
|
||||
|
||||
struct ERROR_STATUS
|
||||
{
|
||||
bool pendingError;
|
||||
|
@ -62,9 +64,12 @@ struct ERROR_STATUS
|
|||
CST_RUNTIME
|
||||
};
|
||||
|
||||
STAGE stage;
|
||||
std::string message;
|
||||
std::string failingObject;
|
||||
int failingPosition;
|
||||
|
||||
std::string Format() const;
|
||||
};
|
||||
|
||||
|
||||
|
@ -230,6 +235,15 @@ private:
|
|||
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
|
||||
{
|
||||
public:
|
||||
|
@ -289,14 +303,6 @@ public:
|
|||
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 )
|
||||
{
|
||||
auto uop = new UOP( op, new VALUE( value ) );
|
||||
|
@ -317,10 +323,11 @@ public:
|
|||
|
||||
VALUE* Run();
|
||||
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:
|
||||
|
@ -392,28 +399,15 @@ public:
|
|||
/* Check if previous invokation of process() was successful */
|
||||
inline bool IsValid() const
|
||||
{
|
||||
return !m_parseError;
|
||||
}
|
||||
|
||||
const std::string GetParseErrorToken() const
|
||||
{
|
||||
return m_parseErrorToken;
|
||||
}
|
||||
|
||||
const std::string GetParseErrorMessage() const
|
||||
{
|
||||
return m_parseErrorMessage;
|
||||
}
|
||||
|
||||
int GetParseErrorPosition() const
|
||||
{
|
||||
return m_parseErrorPos;
|
||||
return !m_errorStatus.pendingError;
|
||||
}
|
||||
|
||||
void setRoot( LIBEVAL::TREE_NODE root );
|
||||
|
||||
bool Compile( const std::string& aString, UCODE* aCode );
|
||||
std::string DumpTree();
|
||||
void ReportError( const std::string aErrorMsg );
|
||||
ERROR_STATUS GetErrorStatus();
|
||||
|
||||
protected:
|
||||
enum LEXER_STATE
|
||||
|
@ -461,6 +455,7 @@ protected:
|
|||
int m_parseErrorPos;
|
||||
|
||||
std::unique_ptr<UNIT_RESOLVER> m_unitResolver;
|
||||
ERROR_STATUS m_errorStatus;
|
||||
|
||||
TREE_NODE* m_tree;
|
||||
};
|
Loading…
Reference in New Issue