脇坂/pico16o
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
|
ログイン
]
開始行:
[[脇坂/Parthenon]]
#contents
*picoc.yの中身の自分なりの解説? [#b29e95ae]
**ヘッダファイルの読み込みと定義 [#nce24d34]
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include "picoc.h"
#define YYDEBUG 1
#define STACKTOP 127
***関数の定義 [#gd5312ab]
/* prototypes */
Pnode *opr(int oper, int nops, ...);
Pnode *id(int i);
Pnode *con(int value);
void freeNode(Pnode *p);
void sinit(int val);
int ex(Pnode *p, int flag);
void yyerror(char *s);
-たぶんトークンの構造体?
union {
int IntVal; /* integer value */
char Symbol; /* symbol table index */
Pnode *Node; /* node pointer */
};
-トークンと左右どちらから読むかの定義
%token <IntVal> INTEGER
%token <IntVal> HEX
%token <Symbol> VARIABLE
%token WHILE FOR IF FUNCNAME FDEF RETURN FUNC AWT ARD
%token DEF FDEFA HALT
%token <Node> ARG ARGV
%nonassoc IFX
%nonassoc ELSE
%left GE LE EQ NE '>' '<'
%left '+' '-'
%left '*' '/'
%right UMINUS
%left MM PP
%type <Node> astmt stmt expr stmt_list
**Program [#ha21bf0f]
-プログラムのスタート地点。 :の後の文字列が左から順番に$1、$2、$3〜となっている。
program:
init function { exit(0); }
;
***init [#c2fe4c14]
-
init:
/* NULL */ { sinit(STACKTOP);}
;
***function [#te748fd2]
-stmtのPnodeを関数exとfreeNodeに送る。
function:
function stmt { ex($2, 0); freeNode($2); }
| /* NULL */
;
***stmt [#ld882046]
-statementが一つ場合の処理
stmt:
';' { $$ = opr(';', 2, NULL, NULL); }
| astmt ';' { $$ = $1; }
| DEF FUNCNAME '(' ARG ')' stmt { $$ = opr(FDEFA, 1, $6); }
| DEF FUNCNAME '(' DEF ARG ')' stmt { $$ = opr(FDEFA, 1, $7); }
| DEF FUNCNAME '(' ')' stmt { $$ = opr(FDEF, 1, $5); }
| FOR '(' astmt ';' expr ';' astmt ')' stmt { $$ = opr(FOR, 4, $3, $5, $7, $9); }
| WHILE '(' expr ')' stmt { $$ = opr(WHILE, 2, $3, $5); }
| RETURN '(' expr ')' ';' { $$ = opr(RETURN, 1, $3); }
| RETURN expr ';' { $$ = opr(RETURN, 1, $2); }
| RETURN ';' { $$ = opr(RETURN, 0); }
| IF '(' expr ')' stmt %prec IFX { $$ = opr(IF, 2, $3, $5); }
| IF '(' expr ')' stmt ELSE stmt { $$ = opr(IF, 3, $3, $5, $7); }
| '{' stmt_list '}' { $$ = $2; }
| HALT ';' { $$ = opr(HALT, 0); }
;
***astmt [#r32250be]
astmt:
expr { $$ = $1; }
| VARIABLE '=' expr { $$ = opr('=', 2, id($1), $3); }
| VARIABLE PP { $$ = opr('=', 2, id($1), opr('+', 2, id($1), con(1))); }
| VARIABLE MM { $$ = opr('=', 2, id($1), opr('-', 2, id($1), con(1))); }
| VARIABLE '[' expr ']' '=' expr { $$ = opr(AWT, 3, $3, $6, id($1)); }
;
***stmt_list [#jdc19dc1]
-statementが複数ある場合の処理
stmt_list:
stmt { $$ = $1; }
| stmt_list stmt { $$ = opr(';', 2, $1, $2); }
;
***expr [#t1e54396]
-
expr:
INTEGER { $$ = con($1); }
| HEX { $$ = con($1); }
| VARIABLE { $$ = id($1); }
| ARG { $$ = opr(ARGV, 0); }
| '-' expr %prec UMINUS { $$ = opr(UMINUS, 1, $2); }
| VARIABLE '[' expr ']' { $$ = opr(ARD, 2, $3, id($1)); }
| FUNCNAME '(' expr ')' { $$ = opr(FUNC, 1, $3); }
| expr '+' expr { $$ = opr('+', 2, $1, $3); }
| expr '-' expr { $$ = opr('-', 2, $1, $3); }
| expr '<' expr { $$ = opr('<', 2, $1, $3); }
| expr '>' expr { $$ = opr('>', 2, $1, $3); }
| expr GE expr { $$ = opr(GE, 2, $1, $3); }
| expr LE expr { $$ = opr(LE, 2, $1, $3); }
| expr NE expr { $$ = opr(NE, 2, $1, $3); }
| expr EQ expr { $$ = opr(EQ, 2, $1, $3); }
| '(' expr ')' { $$ = $2; }
;
**木を作る部分 [#g4a2a3b7]
***con(int value) [#zaa85f63]
-即値の部分を作っている
Pnode *con(int value) {
Pnode *p;
/* allocate node */
if ((p = malloc(sizeof(Const))) == NULL)
yyerror("out of memory");
/* copy information */
p->type = typeCon;
p->con.value = value;
return p;
}
***id(int i) [#e5d70429]
-変数の部分を作っている
-id.iの中に変数の値が入っている。 a=0,b=1,....
Pnode *id(int i) {
Pnode *p;
/* allocate node */
if ((p = malloc(sizeof(Ident))) == NULL)
yyerror("out of memory");
/* copy information */
p->type = typeId;
p->id.i = i;
return p;
}
***opr(int oper, int nops ,...) [#la74cd5c]
-operandの部分を作っている。
-nopsはPnodeが持っている枝の数。
Pnode *opr(int oper, int nops, ...) {
va_list ap;
Pnode *p;
size_t size;
int i;
/* allocate node */
size = sizeof(Operator) + (nops - 1) * sizeof(Pnode*);
if ((p = malloc(size)) == NULL)
yyerror("out of memory");
/* copy information */
p->type = typeOpr;
p->opr.oper = oper;
p->opr.nops = nops;
va_start(ap, nops);
for (i = 0 ; i < nops ; i++)
p->opr.op[i] = va_arg(ap, Pnode*);
va_end(ap);
return p;
}
***freeNode(Pnode *p) [#rc411861]
-ノードの開放を行う
void freeNode(Pnode *p) {
int i;
if (!p) return;
if (p->type == typeOpr) {
for (i = 0 ; i < p->opr.nops ; i++)
freeNode(p->opr.op[i]);
}
free (p);
}
***yyerror(char *s) [#ae4e022e]
-エラー書き出し
void yyerror(char *s) {
fprintf(stdout, "%s\n", s);
}
***main(int argc ,char *argv[]) [#q9cce4a2]
-
extern int yydebug;
int main(int argc, char *argv[]) {
if(argc==2 && !strcmp(argv[1], "-d")) yydebug=1;
yyparse();
return 0;
}
------------------------------
#comment
終了行:
[[脇坂/Parthenon]]
#contents
*picoc.yの中身の自分なりの解説? [#b29e95ae]
**ヘッダファイルの読み込みと定義 [#nce24d34]
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include "picoc.h"
#define YYDEBUG 1
#define STACKTOP 127
***関数の定義 [#gd5312ab]
/* prototypes */
Pnode *opr(int oper, int nops, ...);
Pnode *id(int i);
Pnode *con(int value);
void freeNode(Pnode *p);
void sinit(int val);
int ex(Pnode *p, int flag);
void yyerror(char *s);
-たぶんトークンの構造体?
union {
int IntVal; /* integer value */
char Symbol; /* symbol table index */
Pnode *Node; /* node pointer */
};
-トークンと左右どちらから読むかの定義
%token <IntVal> INTEGER
%token <IntVal> HEX
%token <Symbol> VARIABLE
%token WHILE FOR IF FUNCNAME FDEF RETURN FUNC AWT ARD
%token DEF FDEFA HALT
%token <Node> ARG ARGV
%nonassoc IFX
%nonassoc ELSE
%left GE LE EQ NE '>' '<'
%left '+' '-'
%left '*' '/'
%right UMINUS
%left MM PP
%type <Node> astmt stmt expr stmt_list
**Program [#ha21bf0f]
-プログラムのスタート地点。 :の後の文字列が左から順番に$1、$2、$3〜となっている。
program:
init function { exit(0); }
;
***init [#c2fe4c14]
-
init:
/* NULL */ { sinit(STACKTOP);}
;
***function [#te748fd2]
-stmtのPnodeを関数exとfreeNodeに送る。
function:
function stmt { ex($2, 0); freeNode($2); }
| /* NULL */
;
***stmt [#ld882046]
-statementが一つ場合の処理
stmt:
';' { $$ = opr(';', 2, NULL, NULL); }
| astmt ';' { $$ = $1; }
| DEF FUNCNAME '(' ARG ')' stmt { $$ = opr(FDEFA, 1, $6); }
| DEF FUNCNAME '(' DEF ARG ')' stmt { $$ = opr(FDEFA, 1, $7); }
| DEF FUNCNAME '(' ')' stmt { $$ = opr(FDEF, 1, $5); }
| FOR '(' astmt ';' expr ';' astmt ')' stmt { $$ = opr(FOR, 4, $3, $5, $7, $9); }
| WHILE '(' expr ')' stmt { $$ = opr(WHILE, 2, $3, $5); }
| RETURN '(' expr ')' ';' { $$ = opr(RETURN, 1, $3); }
| RETURN expr ';' { $$ = opr(RETURN, 1, $2); }
| RETURN ';' { $$ = opr(RETURN, 0); }
| IF '(' expr ')' stmt %prec IFX { $$ = opr(IF, 2, $3, $5); }
| IF '(' expr ')' stmt ELSE stmt { $$ = opr(IF, 3, $3, $5, $7); }
| '{' stmt_list '}' { $$ = $2; }
| HALT ';' { $$ = opr(HALT, 0); }
;
***astmt [#r32250be]
astmt:
expr { $$ = $1; }
| VARIABLE '=' expr { $$ = opr('=', 2, id($1), $3); }
| VARIABLE PP { $$ = opr('=', 2, id($1), opr('+', 2, id($1), con(1))); }
| VARIABLE MM { $$ = opr('=', 2, id($1), opr('-', 2, id($1), con(1))); }
| VARIABLE '[' expr ']' '=' expr { $$ = opr(AWT, 3, $3, $6, id($1)); }
;
***stmt_list [#jdc19dc1]
-statementが複数ある場合の処理
stmt_list:
stmt { $$ = $1; }
| stmt_list stmt { $$ = opr(';', 2, $1, $2); }
;
***expr [#t1e54396]
-
expr:
INTEGER { $$ = con($1); }
| HEX { $$ = con($1); }
| VARIABLE { $$ = id($1); }
| ARG { $$ = opr(ARGV, 0); }
| '-' expr %prec UMINUS { $$ = opr(UMINUS, 1, $2); }
| VARIABLE '[' expr ']' { $$ = opr(ARD, 2, $3, id($1)); }
| FUNCNAME '(' expr ')' { $$ = opr(FUNC, 1, $3); }
| expr '+' expr { $$ = opr('+', 2, $1, $3); }
| expr '-' expr { $$ = opr('-', 2, $1, $3); }
| expr '<' expr { $$ = opr('<', 2, $1, $3); }
| expr '>' expr { $$ = opr('>', 2, $1, $3); }
| expr GE expr { $$ = opr(GE, 2, $1, $3); }
| expr LE expr { $$ = opr(LE, 2, $1, $3); }
| expr NE expr { $$ = opr(NE, 2, $1, $3); }
| expr EQ expr { $$ = opr(EQ, 2, $1, $3); }
| '(' expr ')' { $$ = $2; }
;
**木を作る部分 [#g4a2a3b7]
***con(int value) [#zaa85f63]
-即値の部分を作っている
Pnode *con(int value) {
Pnode *p;
/* allocate node */
if ((p = malloc(sizeof(Const))) == NULL)
yyerror("out of memory");
/* copy information */
p->type = typeCon;
p->con.value = value;
return p;
}
***id(int i) [#e5d70429]
-変数の部分を作っている
-id.iの中に変数の値が入っている。 a=0,b=1,....
Pnode *id(int i) {
Pnode *p;
/* allocate node */
if ((p = malloc(sizeof(Ident))) == NULL)
yyerror("out of memory");
/* copy information */
p->type = typeId;
p->id.i = i;
return p;
}
***opr(int oper, int nops ,...) [#la74cd5c]
-operandの部分を作っている。
-nopsはPnodeが持っている枝の数。
Pnode *opr(int oper, int nops, ...) {
va_list ap;
Pnode *p;
size_t size;
int i;
/* allocate node */
size = sizeof(Operator) + (nops - 1) * sizeof(Pnode*);
if ((p = malloc(size)) == NULL)
yyerror("out of memory");
/* copy information */
p->type = typeOpr;
p->opr.oper = oper;
p->opr.nops = nops;
va_start(ap, nops);
for (i = 0 ; i < nops ; i++)
p->opr.op[i] = va_arg(ap, Pnode*);
va_end(ap);
return p;
}
***freeNode(Pnode *p) [#rc411861]
-ノードの開放を行う
void freeNode(Pnode *p) {
int i;
if (!p) return;
if (p->type == typeOpr) {
for (i = 0 ; i < p->opr.nops ; i++)
freeNode(p->opr.op[i]);
}
free (p);
}
***yyerror(char *s) [#ae4e022e]
-エラー書き出し
void yyerror(char *s) {
fprintf(stdout, "%s\n", s);
}
***main(int argc ,char *argv[]) [#q9cce4a2]
-
extern int yydebug;
int main(int argc, char *argv[]) {
if(argc==2 && !strcmp(argv[1], "-d")) yydebug=1;
yyparse();
return 0;
}
------------------------------
#comment
ページ名: