Re: g_scanner funtions what for?
- From: Andreas Tille <tille physik uni-halle de>
- To: timj gtk org
- cc: GTK User-List <gtk-list redhat com>
- Subject: Re: g_scanner funtions what for?
- Date: Tue, 9 Mar 1999 17:03:06 +0100 (MET)
On Fri, 5 Mar 1999, Tim Janik wrote:
> a GScanner will tokenize your text, that is, it'll return an integer
> for every word or number that appears in its input stream, following
> certain (customizable) rules to perform this translation.
> you still need to write the parsing functions on your own though.
> here's a little test program that will parse
>
> <SYMBOL> = <OPTIONAL-MINUS> <NUMBER> ;
>
> constructs, while skipping "#\n" and "/**/" style comments.
> ...
Thanks for the example. I treid it and it worked so far. Because
I had to scan also other things than floats I modified your
example but wasn't successful. I append my code as attachment.
The code fails in scanning gchar * data. Is there any documentation
to do that right?
Kind regards
Andreas.
#include <glib.h>
/* some test text to be fed into the scanner */
static const gchar *test_text =
( "Datum: 02-16-1999\n"
"Probenname: Hans_1\n"
"Modulator f: 500.0\n"
"Schwingkreis f: 500.0\n"
"Schwingkreis U: 5.0\n"
"Temperatur: 25.0\n"
"Trigger-Delay: -400\n"
"Punktzahl: 8192\n"
"Messzeit: 2.0e-006\n" );
/* define enumeration values to be returned for specific symbols */
enum {
SYMBOL_DATE = G_TOKEN_LAST + 1,
SYMBOL_SAMPLE = G_TOKEN_LAST + 2,
SYMBOL_F_m = G_TOKEN_LAST + 3,
SYMBOL_F_s = G_TOKEN_LAST + 4,
SYMBOL_U_s = G_TOKEN_LAST + 5,
SYMBOL_TEMP = G_TOKEN_LAST + 6,
SYMBOL_DELAY = G_TOKEN_LAST + 7,
SYMBOL_N = G_TOKEN_LAST + 8,
SYMBOL_T = G_TOKEN_LAST + 9
};
/* symbol array */
static const struct {
gchar *symbol_name;
guint symbol_token;
} symbols[] = {
{ "Datum", SYMBOL_DATE, },
{ "Probenname", SYMBOL_SAMPLE, },
{ "Modulator f", SYMBOL_F_m, },
{ "Schwingkreis f", SYMBOL_F_s, },
{ "Schwingkreis U", SYMBOL_U_s, },
{ "Temperatur", SYMBOL_TEMP, },
{ "Trigger-Delay", SYMBOL_DELAY, },
{ "Punktzahl", SYMBOL_N, },
{ "Messzeit", SYMBOL_T, },
{ NULL, 0, },
}, *symbol_p = symbols;
static gchar *date = NULL, *sample = NULL;
static gfloat F_m = 0, F_s = 0, U_s = 0, temp = 0, delay = 0, t = 0;
static gint n = 0;
static guint
parse_symbol (GScanner *scanner)
{
guint symbol;
gboolean negate = FALSE;
/* expect a valid symbol */
g_scanner_get_next_token (scanner);
symbol = scanner->token;
if (symbol < SYMBOL_DATE ||
symbol > SYMBOL_T)
return G_TOKEN_SYMBOL;
/* expect '=' */
g_scanner_get_next_token (scanner);
if (scanner->token != ':')
return '=';
/* feature optional '-' */
g_scanner_peek_next_token (scanner);
if (scanner->next_token == '-')
{
g_scanner_get_next_token (scanner);
negate = !negate;
}
/* expect a float (ints are converted to floats on the fly) */
g_scanner_get_next_token (scanner);
if (scanner->token != G_TOKEN_FLOAT)
return G_TOKEN_FLOAT;
/* make sure the next token is a '\n' */
if (g_scanner_peek_next_token (scanner) != '\n')
{
/* not so, eat up the non-semicolon and error out */
g_scanner_get_next_token (scanner);
return '\n';
}
/* assign value, eat the semicolon and exit successfully */
switch (symbol)
{
case SYMBOL_DATE:
date = scanner->value.v_string;
break;
case SYMBOL_SAMPLE:
sample = scanner->value.v_string;
break;
case SYMBOL_F_m:
F_m = negate ? - scanner->value.v_float : scanner->value.v_float;
break;
case SYMBOL_F_s:
F_s = negate ? - scanner->value.v_float : scanner->value.v_float;
break;
case SYMBOL_U_s:
U_s = negate ? - scanner->value.v_float : scanner->value.v_float;
break;
case SYMBOL_TEMP:
temp = negate ? - scanner->value.v_float : scanner->value.v_float;
break;
case SYMBOL_DELAY:
delay = negate ? - scanner->value.v_float : scanner->value.v_float;
break;
case SYMBOL_N:
n = scanner->value.v_int;
break;
case SYMBOL_T:
t = negate ? - scanner->value.v_float : scanner->value.v_float;
break;
}
g_scanner_get_next_token (scanner);
return G_TOKEN_NONE;
}
int
main (int argc, char *argv[])
{
GScanner *scanner;
guint expected_token;
scanner = g_scanner_new (NULL);
/* adjust lexing behaviour to suit our needs
*/
/* convert non-floats (octal values, hex values...) to G_TOKEN_INT */
scanner->config->numbers_2_int = TRUE;
/* convert G_TOKEN_INT to G_TOKEN_FLOAT */
scanner->config->int_2_float = TRUE;
/* don't return G_TOKEN_SYMBOL, but the symbol's value */
scanner->config->symbol_2_token = TRUE;
/* load symbols into the scanner */
while (symbol_p->symbol_name)
{
g_scanner_add_symbol (scanner,
symbol_p->symbol_name,
GINT_TO_POINTER (symbol_p->symbol_token));
symbol_p++;
}
/* feed in the text */
g_scanner_input_text (scanner, test_text, strlen (test_text));
/* give the error handler an idea on how the input is named */
scanner->input_name = "test text";
/* scanning loop, we parse the input untill it's end is reached,
* the scanner encountered a lexing error, or our sub routine came
* across invalid syntax
*/
do
{
expected_token = parse_symbol (scanner);
g_scanner_peek_next_token (scanner);
}
while (expected_token == G_TOKEN_NONE &&
scanner->next_token != G_TOKEN_EOF &&
scanner->next_token != G_TOKEN_ERROR);
/* give an error message upon syntax errors */
if (expected_token != G_TOKEN_NONE)
g_scanner_unexp_token (scanner, expected_token, NULL, "symbol", NULL, NULL, TRUE);
/* finsish parsing */
g_scanner_destroy (scanner);
/* print results */
g_print ("date: %s, sample: %s\n", date, sample);
g_print ("F_m = %f, F_s = %f, U_s = %f, temp = %f, delay = %f, t = %f\n",
F_m, F_s, U_s, temp, delay, t);
g_print ("n = %i\n", n);
return 0;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]