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-2019 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
37namespace fcml {
38
44public:
46 ErrorContainer &errorContainer,
48 ErrorContainerAwareException(msg, errorContainer, error) {
49 }
50};
51
56public:
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
127 return _throwExceptionOnError;
128 }
129
137 void setThrowExceptionOnError(bool throwExceptionOnError) {
138 _throwExceptionOnError = throwExceptionOnError;
139 }
140
141private:
142 bool _throwExceptionOnError;
143 bool _ignoreUndefinedSymbols;
144 bool _disableSymbolsDeclaration;
145 bool _overrideLabels;
146 bool _allocSymbolTableIfNeeded;
147 bool _enableErrorMessages;
148};
149
154public:
155
163 _ip(ip), _symbolTable(NULL) {
164 }
165
174 ParserContext(SymbolTable *symbolTable, fcml_ip ip = 0) :
175 _ip(ip), _symbolTable(symbolTable) {
176 }
177
178public:
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
228 _ip += ip;
229 }
230
238 return _symbolTable;
239 }
240
248 return _symbolTable;
249 }
250
257 void setSymbolTable(SymbolTable *symbolTable) {
258 _symbolTable = symbolTable;
259 }
260
261private:
262
264 fcml_ip _ip;
266 ParserConfig _config;
268 SymbolTable *_symbolTable;
269
270};
271
276public:
277
283 }
284
291 const ErrorContainer& getErrors() const {
292 return _errors;
293 }
294
302 return _instruction;
303 }
304
311 return _symbol;
312 }
313
318 void clean() {
319 _errors.clean();
320 _symbol.setNotNull(false);
321 _symbol.setValue(Symbol());
322 }
323
324protected:
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
355private:
356
358 ErrorContainer _errors;
360 Nullable<Symbol> _symbol;
362 Instruction _instruction;
363
364};
365
372public:
373
374 static void convert(ParserConfig &src, fcml_st_parser_config &dest) {
380 }
381
382};
383
387class Parser: protected DialectAware, protected SymbolTableAware {
388public:
389
396 Parser(const Dialect &dialect) :
397 _dialect(dialect) {
398 }
399
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
475 }
476
477private:
478
480 const Dialect &_dialect;
481
482};
483
484}
485
486#endif /* FCML_PARSER_HPP_ */
Inherit from this class in order to get access to the native FCML dialect structure.
Definition: fcml_dialect.hpp:98
fcml_st_dialect * extractDialect(const Dialect &dialect) const
Extracts the native FCML dialect from the dialect object.
Definition: fcml_dialect.hpp:122
An abstract dialect.
Definition: fcml_dialect.hpp:41
Base class for all exceptions that are aware of ErrorContainer.
Definition: fcml_errors.hpp:347
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
Wraps multiple errors into one component.
Definition: fcml_errors.hpp:148
fcml_cstring prepareErrorMessage(const fcml_cstring &message) const
Prepares an error message basing on the first error in the container.
Definition: fcml_errors.hpp:283
void clean()
Cleans all errors and warnings.
Definition: fcml_errors.hpp:296
Describes an instruction.
Definition: fcml_common.hpp:7185
Wrapper for nullable value types.
Definition: fcml_common.hpp:120
Parser configuration.
Definition: fcml_parser.hpp:55
bool isAllocSymbolTableIfNeeded() const
Definition: fcml_parser.hpp:72
void setAllocSymbolTableIfNeeded(bool allocSymbolTableIfNeeded)
Definition: fcml_parser.hpp:77
bool isIgnoreUndefinedSymbols() const
Definition: fcml_parser.hpp:102
bool isThrowExceptionOnError() const
Gets true if exception should be thrown in case of error.
Definition: fcml_parser.hpp:126
bool isOverrideLabels() const
Definition: fcml_parser.hpp:112
void setIgnoreUndefinedSymbols(bool ignoreUndefinedSymbols)
Definition: fcml_parser.hpp:107
void setThrowExceptionOnError(bool throwExceptionOnError)
Sets exception on error flag.
Definition: fcml_parser.hpp:137
bool isDisableSymbolsDeclaration() const
Definition: fcml_parser.hpp:82
void setOverrideLabels(bool overrideLabels)
Definition: fcml_parser.hpp:117
void setEnableErrorMessages(bool enableErrorMessages)
Definition: fcml_parser.hpp:97
ParserConfig()
Default constructor.
Definition: fcml_parser.hpp:62
bool isEnableErrorMessages() const
Definition: fcml_parser.hpp:92
void setDisableSymbolsDeclaration(bool disableSymbolsDeclaration)
Definition: fcml_parser.hpp:87
Parser context.
Definition: fcml_parser.hpp:153
void incrementIP(fcml_ip ip)
Increments instruction pointer by given number of bytes.
Definition: fcml_parser.hpp:227
fcml_ip getIp() const
Gets the instruction pointer.
Definition: fcml_parser.hpp:206
ParserContext(fcml_ip ip=0)
Creates a parser context instance for optional instruction pointer.
Definition: fcml_parser.hpp:162
void setSymbolTable(SymbolTable *symbolTable)
Sets a symbol table for the instruction.
Definition: fcml_parser.hpp:257
ParserContext(SymbolTable *symbolTable, fcml_ip ip=0)
Creates a parser context for given symbol table and optional instruction pointer.
Definition: fcml_parser.hpp:174
const ParserConfig & getConfig() const
Gets the parser configuration associated with the context.
Definition: fcml_parser.hpp:186
ParserConfig & getConfig()
Gets the parser configuration associated with the context.
Definition: fcml_parser.hpp:196
SymbolTable * getSymbolTable()
Gets the symbol table associated with the context.
Definition: fcml_parser.hpp:247
void setIp(fcml_ip ip)
Gets a new instruction pointer.
Definition: fcml_parser.hpp:216
const SymbolTable * getSymbolTable() const
Gets the symbol table associated with the context.
Definition: fcml_parser.hpp:237
Parser result.
Definition: fcml_parser.hpp:275
void setInstruction(const Instruction &instruction)
Sets an instruction for the container.
Definition: fcml_parser.hpp:342
void setErrors(const ErrorContainer &errors)
Sets error container for the context.
Definition: fcml_parser.hpp:333
const Nullable< Symbol > & getSymbol() const
Gets declared symbol is there is any.
Definition: fcml_parser.hpp:310
const ErrorContainer & getErrors() const
Gets errors container with parsing errors.
Definition: fcml_parser.hpp:291
ParserResult()
Creates an empty parser result.
Definition: fcml_parser.hpp:282
const Instruction & getInstruction() const
Gets the parsed instruction.
Definition: fcml_parser.hpp:301
void clean()
Cleans the parser result.
Definition: fcml_parser.hpp:318
void setSymbol(const Nullable< Symbol > &symbol)
Sets symbol.
Definition: fcml_parser.hpp:351
Converts objects to their structures counterparts.
Definition: fcml_parser.hpp:371
Parser wrapper.
Definition: fcml_parser.hpp:387
fcml_ceh_error parse(ParserContext &ctx, const fcml_cstring &instruction, ParserResult &parserResult)
Parses instruction given in the parameters.
Definition: fcml_parser.hpp:410
Parser(const Dialect &dialect)
Creates a parser instance for the given dialect.
Definition: fcml_parser.hpp:396
Something failed while parsing.
Definition: fcml_parser.hpp:43
Derive from this class if you really need access to the native symbol table.
Definition: fcml_symbols.hpp:251
fcml_st_symbol_table & extractSymbolTable(SymbolTable &symbolTable)
Extracts the native symbol table for the given symbol table wrapper.
Definition: fcml_symbols.hpp:259
Definition: fcml_symbols.hpp:143
Represents one named symbol with associated value.
Definition: fcml_symbols.hpp:41
fcml_int64_t fcml_ip
General instruction pointer holder.
Definition: fcml_common.h:96
C++ wrappers common classes.
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
C++ wrapper for the base dialect.
fcml_uint16_t fcml_ceh_error
All error codes should be held in variables of this type.
Definition: fcml_errors.h:156
C++ wrapper for the FCML errors handling.
Structures and functions declarations related to FCML parsers.
LIB_EXPORT void LIB_CALL fcml_fn_parser_result_free(fcml_st_parser_result *result)
Cleans result holder.
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.
LIB_EXPORT void LIB_CALL fcml_fn_parser_result_prepare(fcml_st_parser_result *result)
Prepares reusable result holder for parser.
C++ API for symbols handling.
#define FCML_TEXT(x)
Used to code literal strings.
Definition: fcml_types.h:61
@ FCML_CEH_GEC_INTERNAL_ERROR
An internal error occurred.
Definition: fcml_errors.h:49
@ FCML_CEH_GEC_NO_ERROR
Operation succeed.
Definition: fcml_errors.h:42
Parser configuration.
Definition: fcml_parser.h:46
fcml_bool override_labels
Set to true in order to allow overriding existing labels.
Definition: fcml_parser.h:59
fcml_bool ignore_undefined_symbols
Set to true in order to ignore all undefined symbols.
Definition: fcml_parser.h:50
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
fcml_bool enable_error_messages
Enables textual error messages.
Definition: fcml_parser.h:72
fcml_bool disable_symbols_declaration
Disables symbols support.
Definition: fcml_parser.h:54
Parser runtime context.
Definition: fcml_parser.h:76
fcml_st_dialect * dialect
Dialect to be used by parser.
Definition: fcml_parser.h:78
fcml_st_symbol_table symbol_table
Symbol table.
Definition: fcml_parser.h:95
fcml_ip ip
Instruction pointer.
Definition: fcml_parser.h:85
fcml_st_parser_config configuration
Parser configuration.
Definition: fcml_parser.h:80
Reusable result holder.
Definition: fcml_parser.h:99
fcml_st_symbol * symbol
Defined symbol if there is any.
Definition: fcml_parser.h:107
fcml_st_ceh_error_container errors
Parsing errors and warnings going here.
Definition: fcml_parser.h:101
fcml_st_instruction * instruction
Parsed instruction as generic instruction model.
Definition: fcml_parser.h:109