You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

112 lines
3.3 KiB

%{
#include <stdio.h>
#include "inpptree-parser.h"
extern int PTlex (YYSTYPE *lvalp, char **line);
extern int PTparse (char **line, struct INPparseNode **retval);
static void PTerror (char **line, struct INPparseNode **retval, char const *);
#if defined (_MSC_VER)
# define __func__ __FUNCTION__ /* __func__ is C99, but MSC can't */
#endif
%}
%name-prefix="PT"
%output="inpptree-parser.c"
%defines
%pure-parser
%parse-param {char **line}
%lex-param {char **line}
%parse-param {struct INPparseNode **retval}
%union {
double num;
const char *str;
struct INPparseNode *pnode;
}
%token <num> TOK_NUM
%token <str> TOK_STR
%token TOK_LE TOK_LT TOK_GE TOK_GT TOK_EQ TOK_NE
%type <pnode> exp nonempty_arglist
// Operator Precedence
%left ','
%right '?' ':'
%left TOK_OR
%left TOK_AND
%left TOK_EQ TOK_NE
%left TOK_LE TOK_LT TOK_GE TOK_GT
%left '-' '+'
%left '*' '/'
%left '^' /* exponentiation */
%left NEG '!' /* negation--unary minus, and boolean not */
%%
expression:
exp { *retval = $1; }
;
exp:
TOK_NUM { $$ = mknnode($1); }
| TOK_STR { $$ = mksnode($1); }
| exp '+' exp { $$ = mkbnode("+", $1, $3); }
| exp '-' exp { $$ = mkbnode("-", $1, $3); }
| exp '*' exp { $$ = mkbnode("*", $1, $3); }
| exp '/' exp { $$ = mkbnode("/", $1, $3); }
| exp '^' exp { $$ = mkbnode("^", $1, $3); }
| '(' exp ')' { $$ = $2; }
| '-' exp %prec NEG { $$ = mkfnode("-",$2); }
| TOK_STR '(' nonempty_arglist ')' { $$ = mkfnode($1, $3); }
| exp '?' exp ':' exp { $$ = mkfnode("ternary_fcn",
mkbnode(",",
mkbnode(",", $1, $3),
$5)); }
| exp TOK_EQ exp { $$ = mkfnode("eq0", mkbnode("-",$1,$3)); }
| exp TOK_NE exp { $$ = mkfnode("ne0", mkbnode("-",$1,$3)); }
| exp TOK_GT exp { $$ = mkfnode("gt0", mkbnode("-",$1,$3)); }
| exp TOK_LT exp { $$ = mkfnode("lt0", mkbnode("-",$1,$3)); }
| exp TOK_GE exp { $$ = mkfnode("ge0", mkbnode("-",$1,$3)); }
| exp TOK_LE exp { $$ = mkfnode("le0", mkbnode("-",$1,$3)); }
| exp TOK_OR exp { $$ = mkfnode("ne0",
mkbnode("+",
mkfnode("ne0", $1),
mkfnode("ne0", $3))); }
| exp TOK_AND exp { $$ = mkfnode("eq0",
mkbnode("+",
mkfnode("eq0", $1),
mkfnode("eq0", $3))); }
| '!' exp { $$ = mkfnode("eq0", $2); }
;
nonempty_arglist:
exp
| nonempty_arglist ',' exp { $$ = mkbnode(",", $1, $3); }
%%
/* Called by yyparse on error. */
static void
PTerror (char **line, struct INPparseNode **retval, char const *s)
{
fprintf (stderr, "%s: %s\n", __func__, s);
}