fcml  1.2.2
fcml_parser.hpp
Go to the documentation of this file.
1 /*
2  * FCML - Free Code Manipulation Library.
3  * Copyright (C) 2010-2020 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  ErrorContainer &errorContainer,
48  ErrorContainerAwareException(msg, errorContainer, error) {
49  }
50 };
51 
55 class ParserConfig {
56 public:
57 
63  _throwExceptionOnError(true),
64  _ignoreUndefinedSymbols(false),
65  _disableSymbolsDeclaration(true),
66  _overrideLabels(false),
67  _allocSymbolTableIfNeeded(false),
68  _enableErrorMessages(true) {
69  }
70 
73  return _allocSymbolTableIfNeeded;
74  }
75 
77  void setAllocSymbolTableIfNeeded(bool allocSymbolTableIfNeeded) {
78  _allocSymbolTableIfNeeded = allocSymbolTableIfNeeded;
79  }
80 
83  return _disableSymbolsDeclaration;
84  }
85 
87  void setDisableSymbolsDeclaration(bool disableSymbolsDeclaration) {
88  _disableSymbolsDeclaration = disableSymbolsDeclaration;
89  }
90 
92  bool isEnableErrorMessages() const {
93  return _enableErrorMessages;
94  }
95 
97  void setEnableErrorMessages(bool enableErrorMessages) {
98  _enableErrorMessages = enableErrorMessages;
99  }
100 
103  return _ignoreUndefinedSymbols;
104  }
105 
107  void setIgnoreUndefinedSymbols(bool ignoreUndefinedSymbols) {
108  _ignoreUndefinedSymbols = ignoreUndefinedSymbols;
109  }
110 
112  bool isOverrideLabels() const {
113  return _overrideLabels;
114  }
115 
117  void setOverrideLabels(bool overrideLabels) {
118  _overrideLabels = overrideLabels;
119  }
120 
126  bool isThrowExceptionOnError() const {
127  return _throwExceptionOnError;
128  }
129 
137  void setThrowExceptionOnError(bool throwExceptionOnError) {
138  _throwExceptionOnError = throwExceptionOnError;
139  }
140 
141 private:
142  bool _throwExceptionOnError;
143  bool _ignoreUndefinedSymbols;
144  bool _disableSymbolsDeclaration;
145  bool _overrideLabels;
146  bool _allocSymbolTableIfNeeded;
147  bool _enableErrorMessages;
148 };
149 
154 public:
155 
163  _ip(ip), _symbolTable(NULL) {
164  }
165 
174  ParserContext(SymbolTable *symbolTable, fcml_ip ip = 0) :
175  _ip(ip), _symbolTable(symbolTable) {
176  }
177 
178 public:
179 
186  const ParserConfig& getConfig() const {
187  return _config;
188  }
189 
197  return _config;
198  }
199 
206  fcml_ip getIp() const {
207  return _ip;
208  }
209 
216  void setIp(fcml_ip ip) {
217  _ip = ip;
218  }
219 
227  void incrementIP(fcml_ip ip) {
228  _ip += ip;
229  }
230 
237  const SymbolTable* getSymbolTable() const {
238  return _symbolTable;
239  }
240 
248  return _symbolTable;
249  }
250 
257  void setSymbolTable(SymbolTable *symbolTable) {
258  _symbolTable = symbolTable;
259  }
260 
261 private:
262 
264  fcml_ip _ip;
266  ParserConfig _config;
268  SymbolTable *_symbolTable;
269 
270 };
271 
276 public:
277 
283  }
284 
291  const ErrorContainer& getErrors() const {
292  return _errors;
293  }
294 
301  const Instruction& getInstruction() const {
302  return _instruction;
303  }
304 
310  const Nullable<Symbol>& getSymbol() const {
311  return _symbol;
312  }
313 
318  void clean() {
319  _errors.clean();
320  _symbol.setNotNull(false);
321  _symbol.setValue(Symbol());
322  }
323 
324 protected:
325 
326  friend class Parser;
327 
333  void setErrors(const ErrorContainer &errors) {
334  _errors = errors;
335  }
336 
342  void setInstruction(const Instruction &instruction) {
343  _instruction = instruction;
344  }
345 
351  void setSymbol(const Nullable<Symbol> &symbol) {
352  _symbol = symbol;
353  }
354 
355 private:
356 
358  ErrorContainer _errors;
360  Nullable<Symbol> _symbol;
362  Instruction _instruction;
363 
364 };
365 
372 public:
373 
374  static void convert(ParserConfig &src, fcml_st_parser_config &dest) {
379  dest.override_labels = src.isOverrideLabels();
380  }
381 
382 };
383 
387 class Parser: protected DialectAware, protected SymbolTableAware {
388 public:
389 
396  Parser(const Dialect &dialect) :
397  _dialect(dialect) {
398  }
399 
410  fcml_ceh_error parse(ParserContext &ctx, const fcml_cstring &instruction,
411  ParserResult &parserResult) {
412 
413  // Prepare parser context.
414  fcml_st_parser_context context = { 0 };
415  ParserTypeConverter::convert(ctx.getConfig(), context.configuration);
416  context.ip = ctx.getIp();
417  SymbolTable *symbolTable = ctx.getSymbolTable();
418  context.symbol_table =
419  (symbolTable) ? extractSymbolTable(*symbolTable) : NULL;
420  context.dialect = extractDialect(_dialect);
421 
422  fcml_st_parser_result parser_result;
423  ::fcml_fn_parser_result_prepare(&parser_result);
424 
425  try {
426 
427  parserResult.clean();
428 
429  // Prepare instruction.
430  fcml_ceh_error error = ::fcml_fn_parse(&context,
431  instruction.c_str(), &parser_result);
432 
433  ErrorContainer errorContainer;
434  ErrorTypeConverter::convert(parser_result.errors, errorContainer);
435 
436  parserResult.setErrors(errorContainer);
437 
438  if (!error && !parser_result.instruction) {
439  // Just in case, it should never happen.
441  }
442 
443  if (error && ctx.getConfig().isThrowExceptionOnError()) {
444  ::fcml_fn_parser_result_free(&parser_result);
446  errorContainer.prepareErrorMessage(
447  FCML_TEXT("Parsing failed")), errorContainer,
448  error);
449  }
450 
451  if (!error) {
452 
453  Instruction parsedInstruction;
454  TypeConverter::convert(*(parser_result.instruction),
455  parsedInstruction);
456 
457  parserResult.setInstruction(parsedInstruction);
458  parserResult.setSymbol(
459  parser_result.symbol ?
460  Symbol(parser_result.symbol->symbol,
461  parser_result.symbol->value) :
462  Symbol());
463 
464  }
465 
466  ::fcml_fn_parser_result_free(&parser_result);
467 
468  } catch (std::exception &exc) {
469  // If anything failed, free assembler results.
470  ::fcml_fn_parser_result_free(&parser_result);
471  throw exc;
472  }
473 
474  return FCML_CEH_GEC_NO_ERROR;
475  }
476 
477 private:
478 
480  const Dialect &_dialect;
481 
482 };
483 
484 }
485 
486 #endif /* FCML_PARSER_HPP_ */
fcml_st_instruction * instruction
Parsed instruction as generic instruction model.
Definition: fcml_parser.h:109
SymbolTable * getSymbolTable()
Gets the symbol table associated with the context.
Definition: fcml_parser.hpp:247
ParserResult()
Creates an empty parser result.
Definition: fcml_parser.hpp:282
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:227
Parser wrapper.
Definition: fcml_parser.hpp:387
void setEnableErrorMessages(bool enableErrorMessages)
Definition: fcml_parser.hpp:97
C++ wrappers common classes.
bool isAllocSymbolTableIfNeeded() const
Definition: fcml_parser.hpp:72
fcml_bool override_labels
Set to true in order to allow overriding existing labels.
Definition: fcml_parser.h:59
fcml_st_symbol_table symbol_table
Symbol table.
Definition: fcml_parser.h:95
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:82
bool isEnableErrorMessages() const
Definition: fcml_parser.hpp:92
fcml_st_symbol * symbol
Defined symbol if there is any.
Definition: fcml_parser.h:107
fcml_bool enable_error_messages
Enables textual error messages.
Definition: fcml_parser.h:72
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:351
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:396
ParserContext(SymbolTable *symbolTable, fcml_ip ip=0)
Creates a parser context for given symbol table and optional instruction pointer. ...
Definition: fcml_parser.hpp:174
ParserContext(fcml_ip ip=0)
Creates a parser context instance for optional instruction pointer.
Definition: fcml_parser.hpp:162
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:410
Parser configuration.
Definition: fcml_parser.h:46
Parser configuration.
Definition: fcml_parser.hpp:55
void setErrors(const ErrorContainer &errors)
Sets error container for the context.
Definition: fcml_parser.hpp:333
Inherit from this class in order to get access to the native FCML dialect structure.
Definition: fcml_dialect.hpp:98
Parser result.
Definition: fcml_parser.hpp:275
fcml_st_dialect * dialect
Dialect to be used by parser.
Definition: fcml_parser.h:78
void setInstruction(const Instruction &instruction)
Sets an instruction for the container.
Definition: fcml_parser.hpp:342
bool isOverrideLabels() const
Definition: fcml_parser.hpp:112
ParserConfig & getConfig()
Gets the parser configuration associated with the context.
Definition: fcml_parser.hpp:196
void setIgnoreUndefinedSymbols(bool ignoreUndefinedSymbols)
Definition: fcml_parser.hpp:107
Derive from this class if you really need access to the native symbol table.
Definition: fcml_symbols.hpp:251
Reusable result holder.
Definition: fcml_parser.h:99
bool isIgnoreUndefinedSymbols() const
Definition: fcml_parser.hpp:102
fcml_int64_t fcml_ip
General instruction pointer holder.
Definition: fcml_common.h:96
C++ wrapper for the base dialect.
void setAllocSymbolTableIfNeeded(bool allocSymbolTableIfNeeded)
Definition: fcml_parser.hpp:77
void setDisableSymbolsDeclaration(bool disableSymbolsDeclaration)
Definition: fcml_parser.hpp:87
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:186
const Instruction & getInstruction() const
Gets the parsed instruction.
Definition: fcml_parser.hpp:301
const ErrorContainer & getErrors() const
Gets errors container with parsing errors.
Definition: fcml_parser.hpp:291
void setSymbolTable(SymbolTable *symbolTable)
Sets a symbol table for the instruction.
Definition: fcml_parser.hpp:257
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:310
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:237
An internal error occurred.
Definition: fcml_errors.h:49
fcml_st_parser_config configuration
Parser configuration.
Definition: fcml_parser.h:80
void setThrowExceptionOnError(bool throwExceptionOnError)
Sets exception on error flag.
Definition: fcml_parser.hpp:137
Describes an instruction.
Definition: fcml_common.hpp:7185
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:206
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:318
Parser context.
Definition: fcml_parser.hpp:153
void setOverrideLabels(bool overrideLabels)
Definition: fcml_parser.hpp:117
Parser runtime context.
Definition: fcml_parser.h:76
fcml_st_ceh_error_container errors
Parsing errors and warnings going here.
Definition: fcml_parser.h:101
An abstract dialect.
Definition: fcml_dialect.hpp:41
Definition: fcml_symbols.hpp:143
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:126
fcml_uint16_t fcml_ceh_error
All error codes should be held in variables of this type.
Definition: fcml_errors.h:156
Converts objects to their structures counterparts.
Definition: fcml_parser.hpp:371
fcml_ip ip
Instruction pointer.
Definition: fcml_parser.h:85
void setIp(fcml_ip ip)
Gets a new instruction pointer.
Definition: fcml_parser.hpp:216
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:69
ParserConfig()
Default constructor.
Definition: fcml_parser.hpp:62