All pastes #23374 Raw Edit

cparse_lemon

public text v1 · immutable
#23374 ·published 2005-09-19 19:18 UTC
rendered paste body
%include {
#include <string.h>
#include <math.h>

#include "cparse_flex_lemon.h"
#include "cparse.h"

static struct configValue value;
yystype lemon_lval;
}

%token_prefix TOKEN_
%token_type {yystype}

%type expr {yystype}
%type NUMBER {yystype}
%type STRING {yystype}
%type SYMBOL {yystype}

%left PLUS MINUS.
%left DIVIDE MULTIPLY.
%left EXCL.
%left YES NO.
%nonassoc INCLUDE EQUALS EOL.

%fallback SYMBOL INTEGER.

%syntax_error {
        printf("Syntax error.\n");
}

%destructor STRING {
        printf("should destruct string: %s\n", %%.str_val);
}

/* The entire input should consist of one parameter list */
input ::= param_list.

/* Parameter list can include assignments and includes */
param_list ::= param_list assignment.
param_list ::= param_list include.
param_list ::= error EOL.
param_list ::= .

assignment ::= SYMBOL(SYM) EQUALS value EOL.    { value.param = SYM.str_val; setConfig(&value); }
assignment ::= boolean SYMBOL(SYM) EOL.         { value.param = SYM.str_val; value.type = CONFIG_BOOLEAN; setConfig(&value); }
assignment ::= SYMBOL(SYM) EOL.                 { setConfigBoolean(SYM.str_val, 1); free(SYM.str_val); }
assignment ::= EOL.

value ::= string_op(A).         { value.value.str_val = A.str_val; value.type = CONFIG_STRING; }
value ::= LPAREN INTEGER RPAREN float_op(A). { value.value.int_val = lrint(A.dbl_val); value.type = CONFIG_INTEGER; }
value ::= float_op(A).          { value.value.dbl_val = A.dbl_val; value.type = CONFIG_FLOAT; }
value ::= SYMBOL(A).            { value.value.str_val = A.str_val; value.type = CONFIG_SYMBOL; }
value ::= EXCL SYMBOL(A).       { struct configValue *cfg = getConfig(A.str_val);
                                  if(cfg) {
                                        switch(cfg->type) {
                                                case CONFIG_STRING:
                                                case CONFIG_SYMBOL:
                                                        lemon_error("! doesn't make sense with symbol");
                                                        break;
                                                case CONFIG_FLOAT:
                                                        value.value.dbl_val = !cfg->value.dbl_val; break;
                                                case CONFIG_INTEGER:
                                                        value.value.int_val = !cfg->value.int_val; break;
                                                case CONFIG_BOOLEAN:
                                                        value.value.int_val = (cfg->value.int_val ? 0 : 1); break;
                                        }
                                        value.type = cfg->type;
                                  } else {
                                        lemon_error("undefined symbol in negation");
                                  }
                                }
value ::= boolean.

string_op(A) ::= STRING(B).                             { A.str_val = B.str_val; }
string_op(A) ::= SYMBOL(B).                             { A.str_val = strdup(getConfigString(B.str_val, "")); }
string_op(A) ::= string_op(B) PLUS string_op(C).        { char *tmp = malloc(strlen(B.str_val) + strlen(C.str_val));
                                                          sprintf(tmp, "%s%s", B.str_val, C.str_val);
                                                          A.str_val = tmp;
                                                          free(B.str_val);
                                                          free(C.str_val);
                                                        }

float_op(A) ::= SYMBOL(B).                      { A.dbl_val = getConfigDouble(B.str_val, 0.0); }
float_op(A) ::= float_op(B) PLUS float_op(C).   { A.dbl_val = B.dbl_val + C.dbl_val; }
float_op(A) ::= float_op(B) MINUS float_op(C).  { A.dbl_val = B.dbl_val - C.dbl_val; }
float_op(A) ::= float_op(B) MULTIPLY float_op(C). { A.dbl_val = B.dbl_val * C.dbl_val; }
float_op(A) ::= float_op(B) DIVIDE float_op(C). { if(C.dbl_val != 0.0) { A.dbl_val = B.dbl_val / C.dbl_val; } else { A.dbl_val = 0.0; lemon_error("divide by zero"); } }
float_op(A) ::= MINUS float_op(B). [EXCL]       { A.dbl_val = -B.dbl_val; }
float_op(A) ::= LPAREN float_op(B) RPAREN.      { A.dbl_val = B.dbl_val; }
float_op(A) ::= NUMBER(B).                      { A.dbl_val = B.dbl_val; }

boolean(A) ::= YES.             { A.int_val = 1; value.type = CONFIG_BOOLEAN; }
boolean(A) ::= NO.              { A.int_val = 0; value.type = CONFIG_BOOLEAN; }
boolean(A) ::= EXCL boolean(B). { A.int_val = !B.int_val; }

include ::= INCLUDE string_op(INC) EOL. { printf("should include %s\n", INC.str_val); }