added QSE_XLI_LEADDIGIT.
enhanced keyword and identifier scanning for xli
This commit is contained in:
parent
3d6f9af82b
commit
99d0e04879
@ -135,6 +135,7 @@ static void print_usage (QSE_FILE* out, int argc, qse_char_t* argv[])
|
|||||||
qse_fprintf (out, QSE_T(" -f keep file inclusion info\n"));
|
qse_fprintf (out, QSE_T(" -f keep file inclusion info\n"));
|
||||||
qse_fprintf (out, QSE_T(" -t keep comment text\n"));
|
qse_fprintf (out, QSE_T(" -t keep comment text\n"));
|
||||||
qse_fprintf (out, QSE_T(" -s allow multi-segmented strings\n"));
|
qse_fprintf (out, QSE_T(" -s allow multi-segmented strings\n"));
|
||||||
|
qse_fprintf (out, QSE_T(" -d allow a leading digit in identifiers\n"));
|
||||||
qse_fprintf (out, QSE_T(" -v perform validation\n"));
|
qse_fprintf (out, QSE_T(" -v perform validation\n"));
|
||||||
qse_fprintf (out, QSE_T(" -m number specify the maximum amount of memory to use in bytes\n"));
|
qse_fprintf (out, QSE_T(" -m number specify the maximum amount of memory to use in bytes\n"));
|
||||||
#if defined(QSE_BUILD_DEBUG)
|
#if defined(QSE_BUILD_DEBUG)
|
||||||
@ -162,9 +163,9 @@ static int handle_args (int argc, qse_char_t* argv[])
|
|||||||
static qse_opt_t opt =
|
static qse_opt_t opt =
|
||||||
{
|
{
|
||||||
#if defined(QSE_BUILD_DEBUG)
|
#if defined(QSE_BUILD_DEBUG)
|
||||||
QSE_T("hi:o:uaftsvm:X:"),
|
QSE_T("hi:o:uaftsdvm:X:"),
|
||||||
#else
|
#else
|
||||||
QSE_T("hi:o:uaftsvm:"),
|
QSE_T("hi:o:uaftsdvm:"),
|
||||||
#endif
|
#endif
|
||||||
lng
|
lng
|
||||||
};
|
};
|
||||||
@ -226,6 +227,10 @@ static int handle_args (int argc, qse_char_t* argv[])
|
|||||||
g_trait |= QSE_XLI_MULSEGSTR;
|
g_trait |= QSE_XLI_MULSEGSTR;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case QSE_T('d'):
|
||||||
|
g_trait |= QSE_XLI_LEADDIGIT;
|
||||||
|
break;
|
||||||
|
|
||||||
case QSE_T('v'):
|
case QSE_T('v'):
|
||||||
g_trait |= QSE_XLI_VALIDATE;
|
g_trait |= QSE_XLI_VALIDATE;
|
||||||
break;
|
break;
|
||||||
|
@ -50,6 +50,7 @@ enum qse_xli_errnum_t
|
|||||||
QSE_XLI_ELXCHR, /**< invalid character '${0} */
|
QSE_XLI_ELXCHR, /**< invalid character '${0} */
|
||||||
QSE_XLI_EXKWNR, /**< @word '${0}' not recognized */
|
QSE_XLI_EXKWNR, /**< @word '${0}' not recognized */
|
||||||
QSE_XLI_EXKWEM, /**< @ not followed by a valid word */
|
QSE_XLI_EXKWEM, /**< @ not followed by a valid word */
|
||||||
|
QSE_XLI_EIDENT, /**< invalid identifier '${0}' */
|
||||||
QSE_XLI_EUDKEY, /**< undefined key '${0}' */
|
QSE_XLI_EUDKEY, /**< undefined key '${0}' */
|
||||||
QSE_XLI_ENOALI, /**< no alias for '${0}' */
|
QSE_XLI_ENOALI, /**< no alias for '${0}' */
|
||||||
QSE_XLI_EILVAL, /**< illegal value for '${0}' */
|
QSE_XLI_EILVAL, /**< illegal value for '${0}' */
|
||||||
@ -86,7 +87,8 @@ enum qse_xli_trait_t
|
|||||||
QSE_XLI_KEEPFILE = (1 << 4), /**< keep inclusion file info */
|
QSE_XLI_KEEPFILE = (1 << 4), /**< keep inclusion file info */
|
||||||
|
|
||||||
QSE_XLI_MULSEGSTR = (1 << 5), /**< support multi-segmented string */
|
QSE_XLI_MULSEGSTR = (1 << 5), /**< support multi-segmented string */
|
||||||
QSE_XLI_VALIDATE = (1 << 6)
|
QSE_XLI_LEADDIGIT = (1 << 6), /**< allow a leading digit in an identifier */
|
||||||
|
QSE_XLI_VALIDATE = (1 << 7)
|
||||||
};
|
};
|
||||||
typedef enum qse_xli_trait_t qse_xli_trait_t;
|
typedef enum qse_xli_trait_t qse_xli_trait_t;
|
||||||
|
|
||||||
|
@ -49,6 +49,7 @@ const qse_char_t* qse_xli_dflerrstr (
|
|||||||
QSE_T("invalid character '${0}'"),
|
QSE_T("invalid character '${0}'"),
|
||||||
QSE_T("'${0}' not recognized"),
|
QSE_T("'${0}' not recognized"),
|
||||||
QSE_T("@ not followed by a valid word"),
|
QSE_T("@ not followed by a valid word"),
|
||||||
|
QSE_T("invalid identifier '${0}'"),
|
||||||
QSE_T("undefined key '${0}'"),
|
QSE_T("undefined key '${0}'"),
|
||||||
QSE_T("no alias for '${0}'"),
|
QSE_T("no alias for '${0}'"),
|
||||||
QSE_T("illegal value for '${0}'"),
|
QSE_T("illegal value for '${0}'"),
|
||||||
|
@ -104,6 +104,7 @@ struct kwent_t
|
|||||||
int type;
|
int type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* note that the keyword must start with @. */
|
||||||
static kwent_t kwtab[] =
|
static kwent_t kwtab[] =
|
||||||
{
|
{
|
||||||
/* keep it sorted by the first field for binary search */
|
/* keep it sorted by the first field for binary search */
|
||||||
@ -420,50 +421,84 @@ retry:
|
|||||||
}
|
}
|
||||||
else if (c == QSE_T('@'))
|
else if (c == QSE_T('@'))
|
||||||
{
|
{
|
||||||
|
/* keyword/directive - start with @ */
|
||||||
|
|
||||||
int type;
|
int type;
|
||||||
|
|
||||||
ADD_TOKEN_CHAR (xli, tok, c);
|
ADD_TOKEN_CHAR (xli, tok, c);
|
||||||
GET_CHAR_TO (xli, c);
|
GET_CHAR_TO (xli, c);
|
||||||
|
|
||||||
if (c != QSE_T('_') && !QSE_ISALPHA (c))
|
if (!QSE_ISALPHA (c))
|
||||||
{
|
{
|
||||||
/* this directive is empty,
|
/* this directive is empty, not followed by a valid word */
|
||||||
* not followed by a valid word */
|
|
||||||
qse_xli_seterror (xli, QSE_XLI_EXKWEM, QSE_NULL, &xli->tok.loc);
|
qse_xli_seterror (xli, QSE_XLI_EXKWEM, QSE_NULL, &xli->tok.loc);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* expect normal identifier starting with an alphabet */
|
/* expect an identifier starting with an alphabet. the identifier
|
||||||
|
* forming a keyword/directory is composed of alphabets. */
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
ADD_TOKEN_CHAR (xli, tok, c);
|
ADD_TOKEN_CHAR (xli, tok, c);
|
||||||
GET_CHAR_TO (xli, c);
|
GET_CHAR_TO (xli, c);
|
||||||
}
|
}
|
||||||
while (c == QSE_T('_') || c == QSE_T('-') || QSE_ISALNUM (c));
|
while (QSE_ISALPHA (c));
|
||||||
|
|
||||||
type = classify_ident (xli, QSE_STR_CSTR(tok->name));
|
type = classify_ident (xli, QSE_STR_CSTR(tok->name));
|
||||||
if (type == TOK_IDENT)
|
if (type == TOK_IDENT)
|
||||||
{
|
{
|
||||||
/* this directive is not recognized */
|
/* this keyword/directive is not recognized */
|
||||||
qse_xli_seterror (xli, QSE_XLI_EXKWNR, QSE_STR_CSTR(xli->tok.name), &xli->tok.loc);
|
qse_xli_seterror (xli, QSE_XLI_EXKWNR, QSE_STR_CSTR(xli->tok.name), &xli->tok.loc);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
SET_TOKEN_TYPE (xli, tok, type);
|
SET_TOKEN_TYPE (xli, tok, type);
|
||||||
}
|
}
|
||||||
else if (c == QSE_T('_') || QSE_ISALPHA (c))
|
else if (c == QSE_T('_') || QSE_ISALPHA (c) ||
|
||||||
|
(!(xli->tok_status & TOK_STATUS_ENABLE_NSTR) &&
|
||||||
|
(xli->opt.trait & QSE_XLI_LEADDIGIT) &&
|
||||||
|
QSE_ISDIGIT(c)))
|
||||||
{
|
{
|
||||||
int type;
|
int lead_digit = QSE_ISDIGIT(c);
|
||||||
|
int all_digits = 1;
|
||||||
|
|
||||||
/* identifier */
|
/* a normal identifier can be composed of wider varieties of characters
|
||||||
|
* than a keyword/directive */
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
ADD_TOKEN_CHAR (xli, tok, c);
|
||||||
|
GET_CHAR_TO (xli, c);
|
||||||
|
|
||||||
|
if (c == QSE_T('_') || c == QSE_T('-') ||
|
||||||
|
c == QSE_T(':') || c == QSE_T('*') ||
|
||||||
|
c == QSE_T('/') || QSE_ISALPHA (c))
|
||||||
|
{
|
||||||
|
all_digits = 0;
|
||||||
|
}
|
||||||
|
else if (lead_digit && QSE_ISDIGIT(c))
|
||||||
|
{
|
||||||
|
/* nothing to do */
|
||||||
|
}
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lead_digit && all_digits)
|
||||||
|
{
|
||||||
|
/* if an identifier begins with a digit, it must contain a non-digits character */
|
||||||
|
qse_xli_seterror (xli, QSE_XLI_EIDENT, QSE_STR_CSTR(xli->tok.name), &xli->tok.loc);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
SET_TOKEN_TYPE (xli, tok, TOK_IDENT);
|
||||||
|
}
|
||||||
|
else if ((xli->tok_status & TOK_STATUS_ENABLE_NSTR) && QSE_ISDIGIT(c))
|
||||||
|
{
|
||||||
|
SET_TOKEN_TYPE (xli, tok, TOK_NSTR);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
ADD_TOKEN_CHAR (xli, tok, c);
|
ADD_TOKEN_CHAR (xli, tok, c);
|
||||||
GET_CHAR_TO (xli, c);
|
GET_CHAR_TO (xli, c);
|
||||||
}
|
}
|
||||||
while (c == QSE_T('_') || c == QSE_T('-') || QSE_ISALNUM (c));
|
while (QSE_ISDIGIT(c));
|
||||||
|
|
||||||
type = classify_ident (xli, QSE_STR_CSTR(tok->name));
|
|
||||||
SET_TOKEN_TYPE (xli, tok, type);
|
|
||||||
}
|
}
|
||||||
else if (c == QSE_T('\''))
|
else if (c == QSE_T('\''))
|
||||||
{
|
{
|
||||||
@ -533,16 +568,6 @@ retry:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((xli->tok_status & TOK_STATUS_ENABLE_NSTR) && QSE_ISDIGIT(c))
|
|
||||||
{
|
|
||||||
SET_TOKEN_TYPE (xli, tok, TOK_NSTR);
|
|
||||||
do
|
|
||||||
{
|
|
||||||
ADD_TOKEN_CHAR (xli, tok, c);
|
|
||||||
GET_CHAR_TO (xli, c);
|
|
||||||
}
|
|
||||||
while (QSE_ISDIGIT(c));
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
n = get_symbols (xli, c, tok);
|
n = get_symbols (xli, c, tok);
|
||||||
@ -667,6 +692,7 @@ static int read_pair (qse_xli_t* xli)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* once the key name is read, enable the numeric string for a value */
|
||||||
xli->tok_status |= TOK_STATUS_ENABLE_NSTR;
|
xli->tok_status |= TOK_STATUS_ENABLE_NSTR;
|
||||||
|
|
||||||
if (get_token (xli) <= -1) goto oops;
|
if (get_token (xli) <= -1) goto oops;
|
||||||
@ -705,7 +731,7 @@ static int read_pair (qse_xli_t* xli)
|
|||||||
{
|
{
|
||||||
/* SCM_KEYALIAS is specified for this particular item. Let the alias be required.
|
/* SCM_KEYALIAS is specified for this particular item. Let the alias be required.
|
||||||
* If KEYALIAS is globally specified with the specific one, it's optional. */
|
* If KEYALIAS is globally specified with the specific one, it's optional. */
|
||||||
qse_xli_seterrnum (xli, QSE_XLI_ENOALI, &key);
|
qse_xli_seterrnum (xli, QSE_XLI_ENOALI, (const qse_cstr_t*)&key);
|
||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -771,6 +797,8 @@ static int read_pair (qse_xli_t* xli)
|
|||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* semicolon read. turn off NSTR */
|
||||||
|
xli->tok_status &= ~TOK_STATUS_ENABLE_NSTR;
|
||||||
if (get_token (xli) <= -1) goto oops;
|
if (get_token (xli) <= -1) goto oops;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
Loading…
Reference in New Issue
Block a user