libeval_compiler: integrated in common/

This commit is contained in:
Tomasz Wlostowski 2020-06-14 01:19:22 +02:00
parent 539984229d
commit aaa91655aa
6 changed files with 79 additions and 51 deletions

View File

@ -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

View File

@ -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

View File

@ -32,7 +32,7 @@
%include {
#include <assert.h>
#include "libeval_compiler.h"
#include <libeval_compiler/libeval_compiler.h>
}
%syntax_error {

View File

@ -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

View File

@ -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;
};