我实现了一个javascript解释器,我在使用bison减少/减少函数声明和函数表达式的语法冲突方面遇到了麻烦。我不是所有与野牛有过的经历,我可以使用一些帮助来理解该做什么。我已经粘贴在野牛输入文件的一个子集下面,用于说明问题:
%define api.pure full
%{
#define YY_DECL int yylex \
(YYSTYPE * yylval_param, yyscan_t yyscanner, parseData *pd)
%}
%union { // yylval
uint32_t slot;
int64_t i;
double d;
}
%{
void yyerror( void *scanner, parseData *pd, char *s, ... );
%}
%lex-param { void *scanner } { parseData *pd }
%parse-param { void *scanner } { parseData *pd }
%token <i> INT
%token <d> NUMBER
%token <slot> STRING
%token <slot> NAME
%token EOS
%token FCN
%token LPAR
%token RPAR
%token SEMI
%token COMMA
%token LBRACE
%token RBRACE
%type <slot> expr exprlist
%type <slot> stmt
%type <slot> paramlist
%type <slot> funcdecl funcexpr
%type <slot> fname
%type <slot> symbol
%type <slot> pgmlist
%start script
%%
script:
EOS
{
pd->beginning = 0;
YYACCEPT;
}
| pgmlist
{
pd->beginning = $1;
YYACCEPT;
}
;
pgmlist:
%empty
{
$$ = newNode(pd, node_endlist, sizeof(Node));
}
| funcdecl pgmlist
{
$$ = newNode(pd, node_list, sizeof(listNode));
listNode *ln = (listNode *)(pd->table + $$);
ln->elem = $1;
}
| stmt pgmlist
{
$$ = newNode(pd, node_list, sizeof(listNode));
listNode *ln = (listNode *)(pd->table + $$);
ln->elem = $1;
}
;
funcdecl:
FCN symbol LPAR paramlist RPAR LBRACE pgmlist RBRACE
{
$$ = newNode(pd, node_fcndecl, sizeof(fcnDeclNode));
fcnDeclNode *fn = (fcnDeclNode *)(pd->table + $$);
memset (fn, 0, sizeof(fcnDeclNode));
fn->name = $2;
fn->params = $4;
fn->body = $7;
}
;
funcexpr:
FCN fname LPAR paramlist RPAR LBRACE pgmlist RBRACE
{
$$ = newNode(pd, node_fcndecl, sizeof(fcnDeclNode));
fcnDeclNode *fn = (fcnDeclNode *)(pd->table + $$);
memset (fn, 0, sizeof(fcnDeclNode));
fn->name = $2;
fn->params = $4;
fn->body = $7;
}
;
fname:
%empty
{
$$ = 0;
}
| NAME
{
fcnDeclNode *fn = (fcnDeclNode *)(pd->table + $1);
fn->hdr->flag |= flag_decl | flag_lval;
$$ = $1;
}
;
stmt:
exprlist SEMI
{
$$ = $1;
}
;
symbol:
NAME
{
$$ = newNode(pd, node_var, sizeof(symNode));
symNode *sn = (symNode *)(pd->table + $$);
sn->name = $1;
}
;
expr:
NUMBER
{
$$ = newNode(pd, node_num, sizeof(numNode));
numNode *nn = (numNode *)(pd->table + $$);
nn->value = $1;
}
| STRING
{
$$ = $1;
}
| funcexpr
{
$$ = $1;
}
;
exprlist: // non-empty
expr
{
newNode(pd, node_endlist, sizeof(Node));
}
| expr COMMA exprlist
{
$$ = newNode(pd, node_list, sizeof(listNode));
listNode *ln = (listNode *)(pd->table + $$);
ln->elem = $1;
}
;
paramlist:
%empty
{
$$ = newNode(pd, node_endlist, sizeof(Node));
}
| symbol
{
symNode *sn = (symNode *)(pd->table + $1);
sn->hdr->flag |= flag_decl;
$$ = newNode(pd, node_list, sizeof(listNode));
listNode *ln = (listNode *)(pd->table + $$);
ln->elem = $1;
}
| symbol COMMA paramlist
{
symNode *sn = (symNode *)(pd->table + $1);
sn->hdr->flag |= flag_decl;
$$ = newNode(pd, node_list, sizeof(listNode));
listNode *ln = (listNode *)(pd->table + $$);
ln->elem = $1;
}
;
%%
void yyerror( void *scanner, parseData *pd, char *s, ... )
{
fprintf(stderr, "yyerror: %s\n", s);
}
答案 0 :(得分:2)
我通过认识到函数表达式只能用作赋值,声明值,参数,数组元素或对象值来解决问题。我放弃了立即调用的情况。它本身并不需要被引入一般表达式。
我以前用同样的方法解决了对象文字的制作。这是我实施的javascript子集的完整语法:
%define api.pure full
%error-verbose
%{
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "jsdb.h"
#define YY_DECL int yylex \
(YYSTYPE * yylval_param, yyscan_t yyscanner, parseData *pd)
%}
%union { // yylval
uint32_t slot;
int64_t i;
double d;
}
%{
#include "jsdb.lex.h"
static bool debug = true;
void yyerror( void *scanner, parseData *pd, char *s, ... );
%}
%lex-param { void *scanner } { parseData *pd }
%parse-param { void *scanner } { parseData *pd }
%token <i> INT
%token <d> NUMBER
%token <slot> STRING
%token <slot> NAME
%token EOS
%token IF
%token ELSE
%token WHILE
%token DO
%token FOR
%token FCN
%token VAR
%token RETURN
%token CONTINUE
%token BREAK
%token AMPER
%token LPAR
%token RPAR
%token SEMI
%token COMMA
%token LBRACE
%token RBRACE
%token LBRACK
%token RBRACK
%token COLON
%token DOT
%right RPAR ELSE
%precedence PLUS_ASSIGN MINUS_ASSIGN ASSIGN
%left LT LE EQ NEQ GT GE
%left PLUS MINUS
%left TIMES DIV
%precedence UMINUS
%precedence LPAR
%precedence LBRACK
%precedence DOT
%type <slot> expr exprlist
%type <slot> decl decllist
%type <slot> arg arglist
%type <slot> stmt stmtlist
%type <slot> paramlist
%type <slot> elem elemlist
%type <slot> lval objlit
%type <slot> arrayelem arraylist
%type <slot> funcdef funcexpr
%type <slot> fname pgmlist
%type <slot> symbol optexpr
%start script
%%
script:
EOS
{
if (debug) printf("script -> EOS\n");
pd->beginning = 0;
YYACCEPT;
}
| pgmlist
{
if (debug) printf("script -> pgmlist\n");
pd->beginning = $1;
YYACCEPT;
}
;
pgmlist:
%empty
{
if (debug) printf("pgmlist -> _empty_\n");
$$ = newNode(pd, node_endlist, sizeof(Node));
}
| stmt pgmlist
{
if (debug) printf("pgmlist -> stmt pgmlist\n");
$$ = newNode(pd, node_list, sizeof(listNode));
listNode *ln = (listNode *)(pd->table + $$);
ln->elem = $1;
}
| funcdef pgmlist
{
if (debug) printf("pgmlist -> funcdef pgmlist\n");
$$ = newNode(pd, node_list, sizeof(listNode));
listNode *ln = (listNode *)(pd->table + $$);
ln->elem = $1;
}
;
funcdef:
FCN symbol LPAR paramlist RPAR LBRACE stmtlist RBRACE
{
if (debug) printf("funcdef -> symbol fname LPAR paramlist RPAR LBRACE stmtlist RBRACE\n");
$$ = newNode(pd, node_fcnexpr, sizeof(fcnDeclNode));
fcnDeclNode *fn = (fcnDeclNode *)(pd->table + $$);
memset (fn, 0, sizeof(fcnDeclNode));
fn->hdr->flag |= flag_decl;
fn->name = $2;
fn->params = $4;
fn->body = $7;
}
;
funcexpr:
FCN fname LPAR paramlist RPAR LBRACE stmtlist RBRACE
{
if (debug) printf("funcexpr -> FCN fname LPAR paramlist RPAR LBRACE stmtlist RBRACE\n");
$$ = newNode(pd, node_fcnexpr, sizeof(fcnDeclNode));
fcnDeclNode *fn = (fcnDeclNode *)(pd->table + $$);
memset (fn, 0, sizeof(fcnDeclNode));
fn->name = $2;
fn->params = $4;
fn->body = $7;
}
;
fname:
%empty
{
if (debug) printf("fname -> _empty_\n");
$$ = 0;
}
| NAME
{
if (debug) printf("fname -> NAME\n");
$$ = $1;
}
;
stmt:
IF LPAR expr RPAR stmt
{
if (debug) printf("stmt -> IF LPAR expr RPAR stmt\n");
$$ = newNode(pd, node_ifthen, sizeof(ifThenNode));
ifThenNode *ifthen = (ifThenNode *)(pd->table + $$);
ifthen->condexpr = $3;
ifthen->thenstmt = $5;
ifthen->elsestmt = 0;
}
| IF LPAR expr RPAR stmt ELSE stmt
{
if (debug) printf("stmt -> IF LPAR expr RPAR stmt ELSE stmt\n");
$$ = newNode(pd, node_ifthen, sizeof(ifThenNode));
ifThenNode *ifthen = (ifThenNode *)(pd->table + $$);
ifthen->condexpr = $3;
ifthen->thenstmt = $5;
ifthen->elsestmt = $7;
}
| RETURN optexpr SEMI
{
if (debug) printf("stmt -> RETURN optexpr SEMI\n");
$$ = newNode(pd, node_return, sizeof(exprNode));
exprNode *en = (exprNode *)(pd->table + $$);
en->expr = $2;
}
| BREAK SEMI
{
if (debug) printf("stmt -> BREAK SEMI\n");
$$ = newNode(pd, node_return, sizeof(exprNode));
exprNode *en = (exprNode *)(pd->table + $$);
en->hdr->flag |= flag_break;
}
| CONTINUE SEMI
{
if (debug) printf("stmt -> CONTINUE SEMI\n");
$$ = newNode(pd, node_return, sizeof(exprNode));
exprNode *en = (exprNode *)(pd->table + $$);
en->hdr->flag |= flag_continue;
}
| WHILE LPAR expr RPAR stmt
{
if (debug) printf("stmt -> WHILE LPAR expr RPAR stmt\n");
$$ = newNode(pd, node_while, sizeof(whileNode));
whileNode *wn = (whileNode *)(pd->table + $$);
wn->cond = $3;
wn->stmt = $5;
}
| DO stmt WHILE LPAR expr RPAR SEMI
{
if (debug) printf("stmt -> DO stmt WHILE LPAR expr RPAR SEMI\n");
$$ = newNode(pd, node_dowhile, sizeof(whileNode));
whileNode *wn = (whileNode *)(pd->table + $$);
wn->cond = $5;
wn->stmt = $2;
}
| FOR LPAR expr SEMI expr SEMI expr RPAR stmt
{
if (debug) printf("stmt -> FOR LPAR expr SEMI expr SEMI expr RPAR stmt\n");
$$ = newNode(pd, node_for, sizeof(forNode));
forNode *fn = (forNode *)(pd->table + $$);
fn->init = $3;
fn->cond = $5;
fn->incr = $7;
fn->stmt = $9;
}
| LBRACE stmtlist RBRACE
{
if (debug) printf("stmt -> LBRACE stmtlist RBRACE\n");
$$ = $2;
}
| VAR decllist SEMI
{
if (debug) printf("stmt -> VAR decllist SEMI\n");
$$ = $2;
}
| exprlist SEMI
{
if (debug) printf("stmt -> exprlist SEMI\n");
$$ = $1;
}
| SEMI
{
if (debug) printf("stmt -> _empty_\n");
$$ = 0;
}
;
stmtlist:
%empty
{
if (debug) printf("stmtlist -> _empty_\n");
$$ = newNode(pd, node_endlist, sizeof(Node));
}
| stmt stmtlist
{
if (debug) printf("stmtlist -> stmt stmtlist\n");
$$ = newNode(pd, node_list, sizeof(listNode));
listNode *ln = (listNode *)(pd->table + $$);
ln->elem = $1;
}
;
symbol:
NAME
{
if (debug) {
stringNode *sn = (stringNode *)(pd->table + $1);
printf("symbol -> NAME[%.*s]\n", sn->hdr->aux, sn->string);
}
$$ = newNode(pd, node_var, sizeof(symNode));
symNode *sn = (symNode *)(pd->table + $$);
sn->name = $1;
}
;
decl:
symbol
{
if (debug) printf("decl -> symbol\n");
symNode *sn = (symNode *)(pd->table + $1);
sn->hdr->flag |= flag_decl;
$$ = $1;
}
| symbol ASSIGN expr
{
if (debug) printf("decl -> symbol ASSIGN expr\n");
symNode *sn = (symNode *)(pd->table + $1);
sn->hdr->flag |= flag_lval | flag_decl;
$$ = newNode(pd, node_assign, sizeof(binaryNode));
binaryNode *bn = (binaryNode *)(pd->table + $$);
bn->hdr->aux = pm_assign;
bn->right = $3;
bn->left = $1;
}
| symbol ASSIGN funcexpr
{
if (debug) printf("decl -> symbol ASSIGN funcexpr\n");
symNode *sn = (symNode *)(pd->table + $1);
sn->hdr->flag |= flag_lval | flag_decl;
$$ = newNode(pd, node_assign, sizeof(binaryNode));
binaryNode *bn = (binaryNode *)(pd->table + $$);
bn->hdr->aux = pm_assign;
bn->right = $3;
bn->left = $1;
}
| symbol ASSIGN objlit
{
if (debug) printf("decl -> symbol ASSIGN objlit\n");
symNode *sn = (symNode *)(pd->table + $1);
sn->hdr->flag |= flag_lval | flag_decl;
$$ = newNode(pd, node_assign, sizeof(binaryNode));
binaryNode *bn = (binaryNode *)(pd->table + $$);
bn->hdr->aux = pm_assign;
bn->right = $3;
bn->left = $1;
}
;
decllist:
decl
{
if (debug) printf("decllist -> decl\n");
newNode(pd, node_endlist, sizeof(Node));
$$ = newNode(pd, node_list, sizeof(listNode));
listNode *ln = (listNode *)(pd->table + $$);
ln->elem = $1;
}
|
decl COMMA decllist
{
if (debug) printf("decllist -> decl COMMA decllist\n");
$$ = newNode(pd, node_list, sizeof(listNode));
listNode *ln = (listNode *)(pd->table + $$);
ln->elem = $1;
}
;
expr:
expr LT expr
{
if (debug) printf("expr -> expr LT expr\n");
$$ = newNode(pd, node_lt, sizeof(binaryNode));
binaryNode *bn = (binaryNode *)(pd->table + $$);
bn->right = $3;
bn->left = $1;
}
| expr LE expr
{
if (debug) printf("expr -> expr LE expr\n");
$$ = newNode(pd, node_le, sizeof(binaryNode));
binaryNode *bn = (binaryNode *)(pd->table + $$);
bn->right = $3;
bn->left = $1;
}
| expr EQ expr
{
if (debug) printf("expr -> expr EQ expr\n");
$$ = newNode(pd, node_eq, sizeof(binaryNode));
binaryNode *bn = (binaryNode *)(pd->table + $$);
bn->right = $3;
bn->left = $1;
}
| expr NEQ expr
{
if (debug) printf("expr -> expr NEQ expr\n");
$$ = newNode(pd, node_ne, sizeof(binaryNode));
binaryNode *bn = (binaryNode *)(pd->table + $$);
bn->right = $3;
bn->left = $1;
}
| expr GE expr
{
if (debug) printf("expr -> expr GE expr\n");
$$ = newNode(pd, node_ge, sizeof(binaryNode));
binaryNode *bn = (binaryNode *)(pd->table + $$);
bn->right = $3;
bn->left = $1;
}
| expr GT expr
{
if (debug) printf("expr -> expr GT expr\n");
$$ = newNode(pd, node_gt, sizeof(binaryNode));
binaryNode *bn = (binaryNode *)(pd->table + $$);
bn->right = $3;
bn->left = $1;
}
| expr PLUS expr
{
if (debug) printf("expr -> expr PLUS expr\n");
$$ = newNode(pd, node_plus, sizeof(binaryNode));
binaryNode *bn = (binaryNode *)(pd->table + $$);
bn->right = $3;
bn->left = $1;
}
| expr MINUS expr
{
if (debug) printf("expr -> expr MINUS expr\n");
$$ = newNode(pd, node_minus, sizeof(binaryNode));
binaryNode *bn = (binaryNode *)(pd->table + $$);
bn->right = $3;
bn->left = $1;
}
| expr TIMES expr
{
if (debug) printf("expr -> expr TIMES expr\n");
$$ = newNode(pd, node_times, sizeof(binaryNode));
binaryNode *bn = (binaryNode *)(pd->table + $$);
bn->right = $3;
bn->left = $1;
}
| expr DIV expr
{
if (debug) printf("expr -> expr DIV expr\n");
$$ = newNode(pd, node_div, sizeof(binaryNode));
binaryNode *bn = (binaryNode *)(pd->table + $$);
bn->right = $3;
bn->left = $1;
}
| LPAR exprlist RPAR
{
if (debug) printf("expr -> LPAR expr RPAR\n");
$$ = $2;
}
| MINUS expr %prec UMINUS
{
if (debug) printf("expr -> UMINUS expr\n");
$$ = newNode(pd, node_uminus, sizeof(exprNode));
exprNode *en = (exprNode *)(pd->table + $$);
en->expr = $2;
}
| NUMBER
{
if (debug) printf("expr -> NUMBER[%f]\n", $1);
$$ = newNode(pd, node_num, sizeof(numNode));
numNode *nn = (numNode *)(pd->table + $$);
nn->value = $1;
}
| INT
{
if (debug) printf("expr -> INT[%d]\n", $1);
$$ = newNode(pd, node_int, sizeof(intNode));
intNode *in = (intNode *)(pd->table + $$);
in->value = $1;
}
| STRING
{
if (debug) {
stringNode *sn = (stringNode *)(pd->table + $1);
printf("expr -> STRING[%.*s]\n", sn->hdr->aux, sn->string);
}
$$ = $1;
}
| lval ASSIGN expr
{
if (debug) printf("expr -> lval ASSIGN expr\n");
symNode *sn = (symNode *)(pd->table + $1);
sn->hdr->flag |= flag_lval;
$$ = newNode(pd, node_assign, sizeof(binaryNode));
binaryNode *bn = (binaryNode *)(pd->table + $$);
bn->hdr->aux = pm_assign;
bn->right = $3;
bn->left = $1;
}
| lval ASSIGN funcexpr
{
if (debug) printf("expr -> lval ASSIGN funcexpr\n");
symNode *sn = (symNode *)(pd->table + $1);
sn->hdr->flag |= flag_lval;
$$ = newNode(pd, node_assign, sizeof(binaryNode));
binaryNode *bn = (binaryNode *)(pd->table + $$);
bn->hdr->aux = pm_assign;
bn->right = $3;
bn->left = $1;
}
| lval ASSIGN objlit
{
if (debug) printf("expr -> lval ASSIGN objlit\n");
symNode *sn = (symNode *)(pd->table + $1);
sn->hdr->flag |= flag_lval;
$$ = newNode(pd, node_assign, sizeof(binaryNode));
binaryNode *bn = (binaryNode *)(pd->table + $$);
bn->hdr->aux = pm_assign;
bn->right = $3;
bn->left = $1;
}
| lval PLUS_ASSIGN expr
{
if (debug) printf("expr -> lval PLUS_ASSIGN expr\n");
symNode *sn = (symNode *)(pd->table + $1);
sn->hdr->flag |= flag_lval;
$$ = newNode(pd, node_assign, sizeof(binaryNode));
binaryNode *bn = (binaryNode *)(pd->table + $$);
bn->hdr->aux = pm_add;
bn->right = $3;
bn->left = $1;
}
| lval MINUS_ASSIGN expr
{
if (debug) printf("expr -> lval MINUS_ASSIGN expr\n");
symNode *sn = (symNode *)(pd->table + $1);
sn->hdr->flag |= flag_lval;
$$ = newNode(pd, node_assign, sizeof(binaryNode));
binaryNode *bn = (binaryNode *)(pd->table + $$);
bn->hdr->aux = pm_sub;
bn->right = $3;
bn->left = $1;
}
| expr LPAR arglist RPAR
{
if (debug) printf("expr -> expr LPAR arglist RPAR\n");
$$ = newNode(pd, node_fcncall, sizeof(fcnCallNode));
fcnCallNode *fc = (fcnCallNode *)(pd->table + $$);
fc->name = $1;
fc->args = $3;
}
| LBRACK arraylist RBRACK
{
if (debug) printf("expr -> LBRACK arraylist RBRACK\n");
$$ = newNode(pd, node_array, sizeof(arrayNode));
arrayNode *an = (arrayNode *)(pd->table + $$);
an->exprlist = $2;
}
| lval
{
if (debug) printf("expr -> lval\n");
$$ = $1;
}
;
optexpr:
%empty
{
if (debug) printf("optexpr -> _empty_\n");
$$ = 0;
}
| expr
{
if (debug) printf("optexpr -> expr\n");
$$ = $1;
}
;
arrayelem:
expr
{
if (debug) printf("arrayelem -> expr\n");
$$ = $1;
}
| funcexpr
{
if (debug) printf("arrayelem -> funcexpr\n");
$$ = $1;
}
| objlit
{
if (debug) printf("arrayelem -> objlit\n");
$$ = $1;
}
;
arraylist:
%empty
{
if (debug) printf("arraylist -> _empty_\n");
newNode(pd, node_endlist, sizeof(Node));
}
| arrayelem
{
if (debug) printf("arraylist -> arrayelem\n");
$$ = newNode(pd, node_list, sizeof(listNode));
listNode *ln = (listNode *)(pd->table + $$);
ln->elem = $1;
}
| arrayelem COMMA arraylist
{
if (debug) printf("arraylist -> arrayelem COMMA arraylist\n");
$$ = newNode(pd, node_list, sizeof(listNode));
listNode *ln = (listNode *)(pd->table + $$);
ln->elem = $1;
}
;
lval:
symbol
{
$$ = $1;
}
| expr DOT NAME
{
if (debug) {
stringNode *sn = (stringNode *)(pd->table + $3);
printf("lval -> expr DOT NAME[%.*s]\n", sn->hdr->aux, sn->string);
}
$$ = newNode(pd, node_lookup, sizeof(binaryNode));
binaryNode *bn = (binaryNode *)(pd->table + $$);
bn->right = $3;
bn->left = $1;
}
| expr LBRACK expr RBRACK
{
if (debug) printf("lval -> expr LBRACK expr RBRACK\n");
$$ = newNode(pd, node_lookup, sizeof(binaryNode));
binaryNode *bn = (binaryNode *)(pd->table + $$);
bn->right = $3;
bn->left = $1;
}
;
exprlist: // non-empty
expr
{
if (debug) printf("exprlist -> expr\n");
newNode(pd, node_endlist, sizeof(Node));
$$ = newNode(pd, node_list, sizeof(listNode));
listNode *ln = (listNode *)(pd->table + $$);
ln->elem = $1;
}
| expr COMMA exprlist
{
if (debug) printf("exprlist -> expr COMMA exprlist\n");
$$ = newNode(pd, node_list, sizeof(listNode));
listNode *ln = (listNode *)(pd->table + $$);
ln->elem = $1;
}
;
objlit:
LBRACE elemlist RBRACE
{
if (debug) printf("objlit -> LBRACE elemlist RBRACE\n");
$$ = newNode(pd, node_obj, sizeof(objNode));
objNode *on = (objNode *)(pd->table + $$);
on->elemlist = $2;
}
;
elemlist:
%empty
{
if (debug) printf("elemlist -> _empty_\n");
$$ = newNode(pd, node_endlist, sizeof(Node));
}
| elem
{
if (debug) printf("elemlist -> elem\n");
$$ = newNode(pd, node_list, sizeof(listNode));
listNode *ln = (listNode *)(pd->table + $$);
ln->elem = $1;
}
| elem COMMA elemlist
{
if (debug) printf("elemlist -> elem COMMA elemlist\n");
$$ = newNode(pd, node_list, sizeof(listNode));
listNode *ln = (listNode *)(pd->table + $$);
ln->elem = $1;
}
;
elem:
NAME COLON expr
{
if (debug) {
stringNode *sn = (stringNode *)(pd->table + $1);
printf("elem -> NAME[%.*s] COLON expr\n", sn->hdr->aux, sn->string);
}
$$ = newNode(pd, node_elem, sizeof(binaryNode));
binaryNode *bn = (binaryNode *)(pd->table + $$);
bn->right = $3;
bn->left = $1;
}
| STRING COLON expr
{
if (debug) {
stringNode *sn = (stringNode *)(pd->table + $1);
printf("elem -> STRING[%.*s] COLON expr\n", sn->hdr->aux, sn->string);
}
$$ = newNode(pd, node_elem, sizeof(binaryNode));
binaryNode *bn = (binaryNode *)(pd->table + $$);
bn->right = $3;
bn->left = $1;
}
| NAME COLON funcexpr
{
if (debug) {
stringNode *sn = (stringNode *)(pd->table + $1);
printf("elem -> NAME[%.*s] COLON funcexpr\n", sn->hdr->aux, sn->string);
}
$$ = newNode(pd, node_elem, sizeof(binaryNode));
binaryNode *bn = (binaryNode *)(pd->table + $$);
bn->right = $3;
bn->left = $1;
}
| NAME COLON objlit
{
if (debug) {
stringNode *sn = (stringNode *)(pd->table + $1);
printf("elem -> NAME[%.*s] COLON objlit\n", sn->hdr->aux, sn->string);
}
$$ = newNode(pd, node_elem, sizeof(binaryNode));
binaryNode *bn = (binaryNode *)(pd->table + $$);
bn->right = $3;
bn->left = $1;
}
| STRING COLON funcexpr
{
if (debug) {
stringNode *sn = (stringNode *)(pd->table + $1);
printf("elem -> STRING[%.*s] COLON funcexpr\n", sn->hdr->aux, sn->string);
}
$$ = newNode(pd, node_elem, sizeof(binaryNode));
binaryNode *bn = (binaryNode *)(pd->table + $$);
bn->right = $3;
bn->left = $1;
}
| STRING COLON objlit
{
if (debug) {
stringNode *sn = (stringNode *)(pd->table + $1);
printf("elem -> STRING[%.*s] COLON objlit\n", sn->hdr->aux, sn->string);
}
$$ = newNode(pd, node_elem, sizeof(binaryNode));
binaryNode *bn = (binaryNode *)(pd->table + $$);
bn->right = $3;
bn->left = $1;
}
;
paramlist:
%empty
{
if (debug) printf("paramlist -> _empty_\n");
$$ = newNode(pd, node_endlist, sizeof(Node));
}
| symbol
{
if (debug) printf("paramlist -> symbol\n");
symNode *sn = (symNode *)(pd->table + $1);
sn->hdr->flag |= flag_decl;
$$ = newNode(pd, node_list, sizeof(listNode));
listNode *ln = (listNode *)(pd->table + $$);
ln->elem = $1;
}
| symbol COMMA paramlist
{
if (debug) printf("paramlist -> symbol COMMA paramlist\n");
symNode *sn = (symNode *)(pd->table + $1);
sn->hdr->flag |= flag_decl;
$$ = newNode(pd, node_list, sizeof(listNode));
listNode *ln = (listNode *)(pd->table + $$);
ln->elem = $1;
}
;
arg:
AMPER symbol
{
if (debug) printf("arg -> AMPER symbol\n");
symNode *sn = (symNode *)(pd->table + $2);
sn->hdr->type = node_ref;
$$ = $2;
}
| expr
{
if (debug) printf("arg -> expr\n");
$$ = $1;
}
| funcexpr
{
if (debug) printf("arg -> funcexpr\n");
$$ = $1;
}
| objlit
{
if (debug) printf("arg -> objlit\n");
$$ = $1;
}
;
arglist:
%empty
{
if (debug) printf("arglist -> _empty_\n");
$$ = newNode(pd, node_endlist, sizeof(Node));
}
| arg
{
if (debug) printf("arglist -> arg\n");
$$ = newNode(pd, node_list, sizeof(listNode));
listNode *ln = (listNode *)(pd->table + $$);
ln->elem = $1;
}
| arg COMMA arglist
{
if (debug) printf("arglist -> arg COMMA arglist\n");
$$ = newNode(pd, node_list, sizeof(listNode));
listNode *ln = (listNode *)(pd->table + $$);
ln->elem = $1;
}
;
%%
void yyerror( void *scanner, parseData *pd, char *s, ... )
{
fprintf(stderr, "yyerror: %s\n", s);
}