fcml  1.1.3
fcml_parser.hpp
Go to the documentation of this file.
1 /*
2  * FCML - Free Code Manipulation Library.
3  * Copyright (C) 2010-2015 Slawomir Wojtasiak
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18  */
19 
27 #ifndef FCML_PARSER_HPP_
28 #define FCML_PARSER_HPP_
29 
30 #include "fcml_common.hpp"
31 #include "fcml_symbols.hpp"
32 #include "fcml_errors.hpp"
33 #include "fcml_dialect.hpp"
34 
35 #include "fcml_parser.h"
36 
37 namespace fcml {
38 
44 public:
46  ErrorContainerAwareException( msg, errorContainer, error ){
47  }
48 };
49 
53 class ParserConfig {
54 public:
55 
61  _throwExceptionOnError(true),
62  _ignoreUndefinedSymbols(false),
63  _disableSymbolsDeclaration(true),
64  _overrideLabels(false),
65  _allocSymbolTableIfNeeded(false),
66  _enableErrorMessages(true) {
67  }
68 
71  return _allocSymbolTableIfNeeded;
72  }
73 
75  void setAllocSymbolTableIfNeeded(bool allocSymbolTableIfNeeded) {
76  _allocSymbolTableIfNeeded = allocSymbolTableIfNeeded;
77  }
78 
81  return _disableSymbolsDeclaration;
82  }
83 
85  void setDisableSymbolsDeclaration(bool disableSymbolsDeclaration) {
86  _disableSymbolsDeclaration = disableSymbolsDeclaration;
87  }
88 
90  bool isEnableErrorMessages() const {
91  return _enableErrorMessages;
92  }
93 
95  void setEnableErrorMessages(bool enableErrorMessages) {
96  _enableErrorMessages = enableErrorMessages;
97  }
98 
101  return _ignoreUndefinedSymbols;
102  }
103 
105  void setIgnoreUndefinedSymbols(bool ignoreUndefinedSymbols) {
106  _ignoreUndefinedSymbols = ignoreUndefinedSymbols;
107  }
108 
110  bool isOverrideLabels() const {
111  return _overrideLabels;
112  }
113 
115  void setOverrideLabels(bool overrideLabels) {
116  _overrideLabels = overrideLabels;
117  }
118 
124  bool isThrowExceptionOnError() const {
125  return _throwExceptionOnError;
126  }
127 
133  void setThrowExceptionOnError(bool throwExceptionOnError) {
134  _throwExceptionOnError = throwExceptionOnError;
135  }
136 
137 private:
138  bool _throwExceptionOnError;
139  bool _ignoreUndefinedSymbols;
140  bool _disableSymbolsDeclaration;
141  bool _overrideLabels;
142  bool _allocSymbolTableIfNeeded;
143  bool _enableErrorMessages;
144 };
145 
150 public:
151 
158  ParserContext( fcml_ip ip = 0 ) :
159  _ip(ip),
160  _symbolTable(NULL) {
161  }
162 
170  ParserContext( SymbolTable *symbolTable, fcml_ip ip = 0 ) :
171  _ip(ip),
172  _symbolTable(symbolTable) {
173  }
174 
175 public:
176 
183  const ParserConfig& getConfig() const {
184  return _config;
185  }
186 
194  return _config;
195  }
196 
203  fcml_ip getIp() const {
204  return _ip;
205  }
206 
213  void setIp(fcml_ip ip) {
214  _ip = ip;
215  }
216 
223  void incrementIP( fcml_ip ip ) {
224  _ip += ip;
225  }
226 
233  const SymbolTable* getSymbolTable() const {
234  return _symbolTable;
235  }
236 
244  return _symbolTable;
245  }
246 
253  void setSymbolTable(SymbolTable* symbolTable) {
254  _symbolTable = symbolTable;
255  }
256 
257 private:
258 
260  fcml_ip _ip;
262  ParserConfig _config;
264  SymbolTable *_symbolTable;
265 
266 };
267 
272 public:
273 
279  }
280 
287  const ErrorContainer& getErrors() const {
288  return _errors;
289  }
290 
297  const Instruction& getInstruction() const {
298  return _instruction;
299  }
300 
306  const Nullable<Symbol> &getSymbol() const {
307  return _symbol;
308  }
309 
314  void clean() {
315  _errors.clean();
316  _symbol.setNotNull(false);
317  _symbol.setValue(Symbol());
318  }
319 
320 protected:
321 
322  friend class Parser;
323 
329  void setErrors(const ErrorContainer& errors) {
330  _errors = errors;
331  }
332 
338  void setInstruction(const Instruction& instruction) {
339  _instruction = instruction;
340  }
341 
347  void setSymbol(const Nullable<Symbol>& symbol) {
348  _symbol = symbol;
349  }
350 
351 private:
352 
354  ErrorContainer _errors;
356  Nullable<Symbol> _symbol;
358  Instruction _instruction;
359 
360 };
361 
368 public:
369 
370  static void convert( ParserConfig &src, fcml_st_parser_config &dest ) {
375  dest.override_labels = src.isOverrideLabels();
376  }
377 
378 };
379 
383 class Parser: protected DialectAware, protected SymbolTableAware {
384 public:
385 
392  Parser( const Dialect &dialect ) :
393  _dialect(dialect) {
394  }
395 
406  fcml_ceh_error parse( ParserContext &ctx, const fcml_cstring &instruction, ParserResult &parserResult ) {
407 
408  // Prepare parser context.
409  fcml_st_parser_context context = {0};
410  ParserTypeConverter::convert( ctx.getConfig(), context.configuration );
411  context.ip = ctx.getIp();
412  SymbolTable *symbolTable = ctx.getSymbolTable();
413  context.symbol_table = ( symbolTable ) ? extractSymbolTable( *symbolTable ) : NULL;
414  context.dialect = extractDialect( _dialect );
415 
416  fcml_st_parser_result parser_result;
417  ::fcml_fn_parser_result_prepare( &parser_result );
418 
419  try {
420 
421  parserResult.clean();
422 
423  // Prepare instruction.
424  fcml_ceh_error error = ::fcml_fn_parse( &context, instruction.c_str(), &parser_result );
425 
426  ErrorContainer errorContainer;
427  ErrorTypeConverter::convert( parser_result.errors, errorContainer );
428 
429  parserResult.setErrors( errorContainer );
430 
431  if( !error && !parser_result.instruction ) {
432  // Just in case, it should never happen.
434  }
435 
436  if( error && ctx.getConfig().isThrowExceptionOnError() ) {
437  ::fcml_fn_parser_result_free( &parser_result );
438  throw ParsingFailedException( errorContainer.prepareErrorMessage( FCML_TEXT("Parsing failed") ), errorContainer, error );
439  }
440 
441  if( !error ) {
442 
443  Instruction parsedInstruction;
444  TypeConverter::convert( *(parser_result.instruction), parsedInstruction );
445 
446  parserResult.setInstruction( parsedInstruction );
447  parserResult.setSymbol( parser_result.symbol ? Symbol( parser_result.symbol->symbol, parser_result.symbol->value ) : Symbol() );
448 
449  }
450 
451  ::fcml_fn_parser_result_free( &parser_result );
452 
453  } catch( std::exception &exc ) {
454  // If anything failed, free assembler results.
455  ::fcml_fn_parser_result_free( &parser_result );
456  throw exc;
457  }
458 
459  return FCML_CEH_GEC_NO_ERROR;
460  }
461 
462 private:
463 
465  const Dialect &_dialect;
466 
467 };
468 
469 }
470 
471 #endif /* FCML_PARSER_HPP_ */
fcml_st_instruction * instruction
Parsed instruction as generic instruction model.
Definition: fcml_parser.h:107
SymbolTable * getSymbolTable()
Gets the symbol table associated with the context.
Definition: fcml_parser.hpp:243
ParserResult()
Creates an empty parser result.
Definition: fcml_parser.hpp:278
Something failed while parsing.
Definition: fcml_parser.hpp:43
void incrementIP(fcml_ip ip)
Increments instruction pointer by given number of bytes.
Definition: fcml_parser.hpp:223
Parser wrapper.
Definition: fcml_parser.hpp:383
void setEnableErrorMessages(bool enableErrorMessages)
Definition: fcml_parser.hpp:95
C++ wrappers common classes.
bool isAllocSymbolTableIfNeeded() const
Definition: fcml_parser.hpp:70
fcml_bool override_labels
Set to true in order to allow overriding existing labels.
Definition: fcml_parser.h:58
fcml_st_symbol_table symbol_table
Symbol table.
Definition: fcml_parser.h:93
std::basic_string< fcml_char > fcml_cstring
By using this type definition here, it will be definitely much easier to support UNICODE in future re...
Definition: fcml_common.hpp:53
bool isDisableSymbolsDeclaration() const
Definition: fcml_parser.hpp:80
bool isEnableErrorMessages() const
Definition: fcml_parser.hpp:90
fcml_st_symbol * symbol
Defined symbol if there is any.
Definition: fcml_parser.h:105
fcml_bool enable_error_messages
Enables textual error messages.
Definition: fcml_parser.h:71
Wrapper for nullable value types.
Definition: fcml_common.hpp:120
#define FCML_TEXT(x)
Used to code literal strings.
Definition: fcml_types.h:61
void setSymbol(const Nullable< Symbol > &symbol)
Sets symbol.
Definition: fcml_parser.hpp:347
Base class for all exceptions that are aware of ErrorContainer.
Definition: fcml_errors.hpp:347
Parser(const Dialect &dialect)
Creates a parser instance for the given dialect.
Definition: fcml_parser.hpp:392
ParserContext(SymbolTable *symbolTable, fcml_ip ip=0)
Creates a parser context for given symbol table and optional instruction pointer. ...
Definition: fcml_parser.hpp:170
ParserContext(fcml_ip ip=0)
Creates a parser context instance for optional instruction pointer.
Definition: fcml_parser.hpp:158
Definition: fcml_assembler.hpp:39
fcml_ceh_error parse(ParserContext &ctx, const fcml_cstring &instruction, ParserResult &parserResult)
Parses instruction given in the parameters.
Definition: fcml_parser.hpp:406
Parser configuration.
Definition: fcml_parser.h:46
Parser configuration.
Definition: fcml_parser.hpp:53
void setErrors(const ErrorContainer &errors)
Sets error container for the context.
Definition: fcml_parser.hpp:329
Inherit from this class in order to get access to the native FCML dialect structure.
Definition: fcml_dialect.hpp:97
Parser result.
Definition: fcml_parser.hpp:271
fcml_st_dialect * dialect
Dialect to be used by parser.
Definition: fcml_parser.h:77
void setInstruction(const Instruction &instruction)
Sets an instruction for the container.
Definition: fcml_parser.hpp:338
bool isOverrideLabels() const
Definition: fcml_parser.hpp:110
ParserConfig & getConfig()
Gets the parser configuration associated with the context.
Definition: fcml_parser.hpp:193
void setIgnoreUndefinedSymbols(bool ignoreUndefinedSymbols)
Definition: fcml_parser.hpp:105
Derive from this class if you really need access to the native symbol table.
Definition: fcml_symbols.hpp:245
Reusable result holder.
Definition: fcml_parser.h:97
bool isIgnoreUndefinedSymbols() const
Definition: fcml_parser.hpp:100
fcml_int64_t fcml_ip
General instruction pointer holder.
Definition: fcml_common.h:95
C++ wrapper for the base dialect.
void setAllocSymbolTableIfNeeded(bool allocSymbolTableIfNeeded)
Definition: fcml_parser.hpp:75
void setDisableSymbolsDeclaration(bool disableSymbolsDeclaration)
Definition: fcml_parser.hpp:85
fcml_bool ignore_undefined_symbols
Set to true in order to ignore all undefined symbols.
Definition: fcml_parser.h:50
Structures and functions declarations related to FCML parsers.
LIB_EXPORT void LIB_CALL fcml_fn_parser_result_prepare(fcml_st_parser_result *result)
Prepares reusable result holder for parser.
const ParserConfig & getConfig() const
Gets the parser configuration associated with the context.
Definition: fcml_parser.hpp:183
const Instruction & getInstruction() const
Gets the parsed instruction.
Definition: fcml_parser.hpp:297
const ErrorContainer & getErrors() const
Gets errors container with parsing errors.
Definition: fcml_parser.hpp:287
void setSymbolTable(SymbolTable *symbolTable)
Sets a symbol table for the instruction.
Definition: fcml_parser.hpp:253
Represents one named symbol with associated value.
Definition: fcml_symbols.hpp:41
const Nullable< Symbol > & getSymbol() const
Gets declared symbol is there is any.
Definition: fcml_parser.hpp:306
Wraps multiple errors into one component.
Definition: fcml_errors.hpp:148
const SymbolTable * getSymbolTable() const
Gets the symbol table associated with the context.
Definition: fcml_parser.hpp:233
An internal error occurred.
Definition: fcml_errors.h:48
fcml_st_parser_config configuration
Parser configuration.
Definition: fcml_parser.h:79
void setThrowExceptionOnError(bool throwExceptionOnError)
Sets exception on error flag.
Definition: fcml_parser.hpp:133
Describes an instruction.
Definition: fcml_common.hpp:6207
LIB_EXPORT fcml_ceh_error LIB_CALL fcml_fn_parse(fcml_st_parser_context *context, const fcml_string instruction, fcml_st_parser_result *result)
Parses given instruction into the generic instruction model.
fcml_ip getIp() const
Gets the instruction pointer.
Definition: fcml_parser.hpp:203
Operation succeed.
Definition: fcml_errors.h:42
fcml_bool disable_symbols_declaration
Disables symbols support.
Definition: fcml_parser.h:54
void clean()
Cleans the parser result.
Definition: fcml_parser.hpp:314
Parser context.
Definition: fcml_parser.hpp:149
void setOverrideLabels(bool overrideLabels)
Definition: fcml_parser.hpp:115
Parser runtime context.
Definition: fcml_parser.h:75
fcml_st_ceh_error_container errors
Parsing errors and warnings going here.
Definition: fcml_parser.h:99
An abstract dialect.
Definition: fcml_dialect.hpp:41
Definition: fcml_symbols.hpp:142
C++ API for symbols handling.
LIB_EXPORT void LIB_CALL fcml_fn_parser_result_free(fcml_st_parser_result *result)
Cleans result holder.
ErrorContainerAwareException(const fcml_cstring &msg, const ErrorContainer &errorContainer, fcml_ceh_error error=FCML_CEH_GEC_NO_ERROR)
Creates an error container aware exception instance and sets basic information for it...
Definition: fcml_errors.hpp:357
bool isThrowExceptionOnError() const
Gets true if exception should be thrown in case of error.
Definition: fcml_parser.hpp:124
fcml_uint16_t fcml_ceh_error
All error codes should be held in variables of this type.
Definition: fcml_errors.h:139
Converts objects to their structures counterparts.
Definition: fcml_parser.hpp:367
fcml_ip ip
Instruction pointer.
Definition: fcml_parser.h:83
void setIp(fcml_ip ip)
Gets a new instruction pointer.
Definition: fcml_parser.hpp:213
C++ wrapper for the FCML errors handling.
fcml_bool alloc_symbol_table_if_needed
By default parser ignores all symbol declarations if there is no symbol table provided in the parser ...
Definition: fcml_parser.h:68
ParserConfig()
Default constructor.
Definition: fcml_parser.hpp:60