You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
167 lines
6.5 KiB
167 lines
6.5 KiB
/*
|
|
* FCML - Free Code Manipulation Library.
|
|
* Copyright (C) 2010-2019 Slawomir Wojtasiak
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
/** @file fcml_parser.h
|
|
* Structures and functions declarations related to FCML parsers
|
|
*
|
|
* @copyright Copyright (C) 2010-2015 Slawomir Wojtasiak. All rights reserved.
|
|
* This project is released under the GNU Lesser General Public License.
|
|
*/
|
|
|
|
#ifndef FCML_PARSER_H_
|
|
#define FCML_PARSER_H_
|
|
|
|
#include "fcml_lib_export.h"
|
|
|
|
#include "fcml_types.h"
|
|
#include "fcml_errors.h"
|
|
#include "fcml_common.h"
|
|
#include "fcml_dialect.h"
|
|
#include "fcml_symbols.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/** Maximal number of character for parsed instruction. */
|
|
#define FCML_PARSER_MAX_INSTRUCTION_LEN 1024
|
|
|
|
/** Parser configuration. */
|
|
typedef struct fcml_st_parser_config {
|
|
/** Set to true in order to ignore all undefined symbols.
|
|
* In such a case every unknown symbol is treated as 0.
|
|
*/
|
|
fcml_bool ignore_undefined_symbols;
|
|
/** Disables symbols support.
|
|
* It set to true every defined label will cause an error.
|
|
*/
|
|
fcml_bool disable_symbols_declaration;
|
|
/** Set to true in order to allow overriding existing labels.
|
|
* If set to false parser returns "Symbol already exists" error when
|
|
* symbol already exists.
|
|
*/
|
|
fcml_bool override_labels;
|
|
/** By default parser ignores all symbol declarations
|
|
* if there is no symbol table provided in the parser
|
|
* context. By setting this value to true you can force
|
|
* the parser to allocate new symbol table when needed.
|
|
* Remember that you are then responsible for freeing it,
|
|
* so this functionality can be a bit dangerous because
|
|
* you have to check the existence of the symbol table
|
|
* every time it should be deallocated.
|
|
*/
|
|
fcml_bool alloc_symbol_table_if_needed;
|
|
// TODO: Support has to be implemented yet.
|
|
/** Enables textual error messages. */
|
|
fcml_bool enable_error_messages;
|
|
} fcml_st_parser_config;
|
|
|
|
/** Parser runtime context. */
|
|
typedef struct fcml_st_parser_context {
|
|
/** Dialect to be used by parser. Defines supported instructions syntax. */
|
|
fcml_st_dialect *dialect;
|
|
/** Parser configuration. */
|
|
fcml_st_parser_config configuration;
|
|
/** Instruction pointer. RIP/EIP register value used as a value for
|
|
* newly declared symbols.
|
|
* This value is never changed by the parser.
|
|
*/
|
|
fcml_ip ip;
|
|
/** Symbol table. It holds symbols added by the user as
|
|
* well as symbols allocated by the parsers (labels). It is
|
|
* very important to free this container on your own
|
|
* because even if it is not allocated by the user it can be
|
|
* set by the parser when the first symbol definition is found.
|
|
* So the most safe way to manage it is to always use
|
|
* "fcml_fn_symbol_table_free" function as soon as context
|
|
* if going to be freed.
|
|
*/
|
|
fcml_st_symbol_table symbol_table;
|
|
} fcml_st_parser_context;
|
|
|
|
/** Reusable result holder */
|
|
typedef struct fcml_st_parser_result {
|
|
/** Parsing errors and warnings going here. */
|
|
fcml_st_ceh_error_container errors;
|
|
/** Defined symbol if there is any.
|
|
* Remember that this symbol is also stored in the context's symbol table.
|
|
* It is the symbol table that is the owner and that is responsible
|
|
* for freeing it.
|
|
*/
|
|
fcml_st_symbol *symbol;
|
|
/** Parsed instruction as generic instruction model. */
|
|
fcml_st_instruction *instruction;
|
|
} fcml_st_parser_result;
|
|
|
|
/**
|
|
* Parses given instruction into the generic instruction model.
|
|
* Parses the textual representation of the instruction using dialect and
|
|
* configuration provided by the parser context. Parsed instruction is returned in the
|
|
* reusable result holder. Result holder has to be allocated by the
|
|
* user and appropriately prepared using fcml_fn_parser_result_prepare()
|
|
* function. As long as the instruction context and the result holder
|
|
* are not shared across multiple function calls parsing process is
|
|
* thread safe.
|
|
*
|
|
* Remember that textual representation of the instruction has to be written
|
|
* using syntax supported by the dialect parser is going to use.
|
|
*
|
|
* @param context Parser runtime context.
|
|
* @param instruction textual representation of the instruction to be parsed.
|
|
* @param result Reusable result holder.
|
|
* @return Error code or FCML_CEH_GEC_NO_ERROR.
|
|
*/
|
|
LIB_EXPORT fcml_ceh_error LIB_CALL fcml_fn_parse(
|
|
fcml_st_parser_context *context, const fcml_string instruction,
|
|
fcml_st_parser_result *result);
|
|
|
|
/**
|
|
* Prepares reusable result holder for parser.
|
|
* Every instance of fcml_st_parser_result structure is reusable from the
|
|
* parser's point of view, so it has to be prepared in the right way in order
|
|
* to allow parser to reuse it correctly. It is up to the library user to
|
|
* allocate space for the holder itself. This function is only responsible
|
|
* for cleaning the structure correctly and preparing it for the first parsing
|
|
* process. Notice that parser has to clean the result holder at the beginning
|
|
* so you can not pass an uninitialized memory block because it can even cause
|
|
* a crash due to illegal memory access.
|
|
*
|
|
* @param result Result holder instance to be prepared.
|
|
*/
|
|
LIB_EXPORT void LIB_CALL fcml_fn_parser_result_prepare(
|
|
fcml_st_parser_result *result);
|
|
|
|
/**
|
|
* Cleans result holder.
|
|
* Frees all memory blocks allocated by the parser and held inside the result
|
|
* holder (Instructions, errors etc.). Notice that result holder itself is
|
|
* not freed and can be even safety reused after call to this function. In fact
|
|
* this function is also called internally by the parser in order to clean
|
|
* result holder before reusing it.
|
|
* @param result Result holder to clean.
|
|
*/
|
|
LIB_EXPORT void LIB_CALL fcml_fn_parser_result_free(
|
|
fcml_st_parser_result *result);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* FCML_PARSER_H_ */
|