/*************************************************************************/
/* Copyright (C) 2019-2020 Amir Plivatsky */
/* All rights reserved */
/* */
/* Use of the link grammar parsing system is subject to the terms of the */
/* license set forth in the LICENSE file included with this software. */
/* This license allows free redistribution and use in source and binary */
/* forms, with or without modification, subject to certain conditions. */
/* */
/*************************************************************************/
#ifndef _DIALECT_H_
#define _DIALECT_H_
#include <ctype.h>
#include <stdint.h>
#include "api-types.h"
#include "dict-structures.h" // cost_eq
#include "string-id.h"
/* dialect_tag costs with a special meaning. See also link-includes.h. */
#define DIALECT_COST_MAX 9999.0F /* Less than that is a real cost */
#define DIALECT_COST_DISABLE 10000.0F
#define DIALECT_SUB 10001.0F /* Sub-dialect (a vector name) */
#define DIALECT_SECTION 10002.0F /* Section header (a vector name) */
/* Used for dialect table entries and Dialect_Option component cost array. */
typedef struct
{
const char *name;
float cost; /* Component cost, DIALECT_SUB or DIALECT_SECTION */
} dialect_tag;
/* An array of dialect table section names (which are dialect vector
* names), indexed by their ordinal number (starting with 1) in the
* "4.0.dialect" file. The 0'th element indicates the index of the default
* section in the dialect table (NO_INDEX if no default entry). The rest
* of the elements (which also include the default section if exists)
* contain the index of their section in the dialect table.) */
typedef struct
{
const char *name;
unsigned int index; /* Dialect table index */
} dialect_section_tag;
#define NO_INDEX ((unsigned int)-1)
/* This struct is kept in the Dictionary struct. */
struct Dialect_s
{
dialect_tag *table; /* A representation of "4.0.dialect." */
String_id *section_set; /* Dialect table section names. */
dialect_section_tag *section; /* Section tags (indexed by section_set id) */
char *kept_input; /* For dialect table string memory XXX */
unsigned int num_table_tags; /* Number of entries in dialect_tag table */
unsigned int num_sections; /* Dialect_section_tag number of entries */
};
/* Dialect object for parse_options_*_dialect(). */
struct dialect_option_s
{
Dictionary dict;
char *conf; /* User dialect setup */
float *cost_table; /* Indexed by Exptag index field */
};
typedef struct dialect_option_s dialect_info;
Dialect *dialect_alloc(void);
void free_dialect(Dialect *);
unsigned int exptag_dialect_add(Dictionary, const char *);
bool setup_dialect(Dictionary, Parse_Options);
void free_cost_table(Parse_Options opts);
bool apply_dialect(Dictionary, Dialect *, unsigned int, Dialect *, dialect_info *);
/**
* Validate that \p name is a valid dialect tag name.
* @param name Dialect tag name
* @return NULL if valid, else the first offending character.
*/
static inline const char *valid_dialect_name(const char *name)
{
if (!isalpha((unsigned char)name[0])) return name;
while (*++name != '\0')
{
if (!isalnum((unsigned char)name[0]) && name[0] != '_' && name[0] != '-')
return name;
}
return NULL;
}
#endif /* _DIALECT_H_ */