aboutsummaryrefslogtreecommitdiff
path: root/src/html.gram.y
diff options
context:
space:
mode:
Diffstat (limited to 'src/html.gram.y')
-rw-r--r--src/html.gram.y161
1 files changed, 105 insertions, 56 deletions
diff --git a/src/html.gram.y b/src/html.gram.y
index bce5e93..fae64ff 100644
--- a/src/html.gram.y
+++ b/src/html.gram.y
@@ -37,4 +37,6 @@ static FILE *tmp_file;
static void out_char (int c);
static void out_value (pp_value_t *val);
+static void deduce_format (pp_value_t *res,
+ const pp_value_t *a, const pp_value_t *b);
%}
@@ -84,5 +86,5 @@ eval : IDENT
| obrace error cbrace
{
- $$.type = unspecified_value;
+ init_value (&$$, unspecified_value, NULL);
}
;
@@ -109,14 +111,14 @@ expr : value
if ($1.type == unspecified_value
|| $3.type == unspecified_value)
- $$.type = unspecified_value;
+ init_value (&$$, unspecified_value, NULL);
else if ($1.type != $3.type)
{
yyerror ("type mismatch in addition");
- $$.type = unspecified_value;
+ init_value (&$$, unspecified_value, NULL);
}
else
{
$$.type = $1.type;
- $$.prec = maxprec ($1.prec, $3.prec);
+ deduce_format (&$$, &$1, &$3);
switch ($1.type)
{
@@ -141,19 +143,19 @@ expr : value
if ($1.type == unspecified_value
|| $3.type == unspecified_value)
- $$.type = unspecified_value;
+ init_value (&$$, unspecified_value, NULL);
else if ($1.type != $3.type)
{
yyerror ("type mismatch in subtraction");
- $$.type = unspecified_value;
+ init_value (&$$, unspecified_value, NULL);
}
else if ($1.type == string_value)
{
yyerror ("subtraction not defined for strings");
- $$.type = unspecified_value;
+ init_value (&$$, unspecified_value, NULL);
}
else
{
$$.type = $1.type;
- $$.prec = maxprec ($1.prec, $3.prec);
+ deduce_format (&$$, &$1, &$3);
$$.v.number = $1.v.number - $3.v.number;
}
@@ -163,19 +165,19 @@ expr : value
if ($1.type == unspecified_value
|| $3.type == unspecified_value)
- $$.type = unspecified_value;
+ init_value (&$$, unspecified_value, NULL);
else if ($1.type != $3.type)
{
yyerror ("type mismatch in multiplication");
- $$.type = unspecified_value;
+ init_value (&$$, unspecified_value, NULL);
}
else if ($1.type == string_value)
{
yyerror ("multiplication not defined for strings");
- $$.type = unspecified_value;
+ init_value (&$$, unspecified_value, NULL);
}
else
{
$$.type = $1.type;
- $$.prec = maxprec ($1.prec, $3.prec);
+ deduce_format (&$$, &$1, &$3);
$$.v.number = $1.v.number * $3.v.number;
}
@@ -185,24 +187,24 @@ expr : value
if ($1.type == unspecified_value
|| $3.type == unspecified_value)
- $$.type = unspecified_value;
+ init_value (&$$, unspecified_value, NULL);
else if ($1.type != $3.type)
{
yyerror ("type mismatch in division");
- $$.type = unspecified_value;
+ init_value (&$$, unspecified_value, NULL);
}
else if ($1.type == string_value)
{
yyerror ("division not defined for strings");
- $$.type = unspecified_value;
+ init_value (&$$, unspecified_value, NULL);
}
else if (fabs ($3.v.number) < 1.0e-5)
{
yyerror ("division by zero");
- $$.type = unspecified_value;
+ init_value (&$$, unspecified_value, NULL);
}
else
{
$$.type = $1.type;
- $$.prec = maxprec ($1.prec, $3.prec);
+ deduce_format (&$$, &$1, &$3);
$$.v.number = $1.v.number / $3.v.number;
}
@@ -211,14 +213,13 @@ expr : value
{
if ($2.type == unspecified_value)
- $$.type = unspecified_value;
+ init_value (&$$, unspecified_value, NULL);
else if ($2.type == string_value)
{
yyerror ("unary minus not defined for strings");
- $$.type = unspecified_value;
+ init_value (&$$, unspecified_value, NULL);
}
else
{
- $$.type = $2.type;
- $$.prec = $2.prec;
+ $$ = $2;
$$.v.number = - $2.v.number;
}
@@ -227,9 +228,9 @@ expr : value
{
if ($2.type == unspecified_value)
- $$.type = unspecified_value;
+ init_value (&$$, unspecified_value, NULL);
else if ($2.type == string_value)
{
yyerror ("unary plus not defined for strings");
- $$.type = unspecified_value;
+ init_value (&$$, unspecified_value, NULL);
}
else
@@ -243,7 +244,7 @@ value : IDENT
| NUMBER
{
- $$.type = numeric_value;
- $$.prec = -1;
- $$.v.number = $1;
+ union value v;
+ v.number = $1;
+ init_value (&$$, numeric_value, &v);
}
;
@@ -310,26 +311,58 @@ out_char (int c)
static void
-out_value (pp_value_t *val)
+deduce_format (pp_value_t *res, const pp_value_t *a, const pp_value_t *b)
{
- switch (val->type)
+ res->prec = maxprec (a->prec, b->prec);
+ if (!a->format && b->format)
{
- case unspecified_value:
- fprintf (tmp_file, "#UNSPECIFIED");
- break;
+ res->fmt = b->fmt;
+ res->format = b->format;
+ }
+ else
+ {
+ res->fmt = a->fmt;
+ res->format = a->format;
+ }
+}
- case numeric_value:
- if (val->prec >= 0)
- fprintf (tmp_file, "%.*f", val->prec, val->v.number);
+
+void
+format_unspecified (FILE *fp, union value v, const char *fmt, int prec)
+{
+ fprintf (fp, "#UNSPECIFIED");
+}
+
+void
+format_numeric (FILE *fp, union value v, const char *fmt, int prec)
+{
+ if (prec >= 0)
+ fprintf (fp, "%.*f", prec, v.number);
else
- fprintf (tmp_file, "%f", val->v.number);
- break;
+ fprintf (fp, "%f", v.number);
+}
- case string_value:
- if (val->prec > 0)
- fprintf (tmp_file, "%.*s", val->prec, val->v.string);
+void
+format_string (FILE *fp, union value v, const char *fmt, int prec)
+{
+ if (fmt)
+ fprintf (fp, fmt, v.string);
+ else if (prec > 0)
+ fprintf (fp, "%.*s", prec, v.string);
else
- fprintf (tmp_file, "%s", val->v.string);
- break;
+ fprintf (fp, "%s", v.string);
}
+
+static value_format_fn default_format[] = {
+ format_unspecified,
+ format_numeric,
+ format_string
+};
+
+static void
+out_value (pp_value_t *val)
+{
+ value_format_fn format =
+ val->format ? val->format : default_format[val->type];
+ format (tmp_file, val->v, val->fmt, val->prec);
}
@@ -357,6 +390,25 @@ free_value (pp_value_t *val)
}
-static void
-add_value (pp_tab_t **ptab, const char *name, pp_value_t *val)
+void
+init_value (pp_value_t *p, value_type type, union value *v)
+{
+ memset (p, 0, sizeof (*p));
+ p->type = type;
+ p->prec = -1;
+ switch (p->type)
+ {
+ case unspecified_value:
+ break;
+ case numeric_value:
+ p->v.number = v->number;
+ break;
+ case string_value:
+ p->v.string = xstrdup (v->string);
+ }
+}
+
+static pp_value_t *
+add_value (pp_tab_t **ptab, const char *name,
+ value_type type, union value *v)
{
pp_tab_t *p;
@@ -375,27 +427,24 @@ add_value (pp_tab_t **ptab, const char *name, pp_value_t *val)
*ptab = p;
}
- p->value = *val;
+ init_value (&p->value, type, v);
+ return &p->value;
}
-void
+pp_value_t *
add_numeric_value (pp_tab_t **ptab, const char *name, double number)
{
- pp_value_t val;
+ union value v;
- val.type = numeric_value;
- val.prec = -1;
- val.v.number = number;
- add_value (ptab, name, &val);
+ v.number = number;
+ return add_value (ptab, name, numeric_value, &v);
}
-void
+pp_value_t *
add_string_value (pp_tab_t **ptab, const char *name, const char *string)
{
- pp_value_t val;
+ union value v;
- val.type = string_value;
- val.prec = -1;
- val.v.string = xstrdup (string);
- add_value (ptab, name, &val);
+ v.string = xstrdup (string);
+ return add_value (ptab, name, string_value, &v);
}

Return to:

Send suggestions and report system problems to the System administrator.