📄 cforms.y
字号:
%{#include "config.h"#include "token.h"#include "comp.h"extern int yyerror();static int keywords = 1;static int last_x = 0, last_y = 0 , *last = &last_x;struct { struct field field; struct viewport viewport; struct picture picture; struct stmt *stmt;} current;struct id { char space[200]; char id[200];};static char *key_lookup(char *key);static char *event_lookup(char *event);static int yylex(void);%}%token <id> PICTURE FIELD LITERAL RVALUE LVALUE POS CENTER MAX PLUS%token <id> MINUS TYPE CHAR ID NUMBER LBRACE RBRACE RPAR LPAR COMMA%token <id> SEMI PROTECTED INVISIBLE FORBIDDEN VIEWPORT CCODE SIZE GLOBAL%token <id> EVENT KEY INT ALNUM VALUE FORGET UPPERCASE HIGHLIGHT FRAME%type <viewport> viewport viewportmembers%type <picture> picture picturemembers%type <field> field fieldmembers type%type <literal> literal%type <event> event eventtype%type <ccode> ccode%type <stmt> stmt intstmt%type <list> module%type <pos> pos size xcommay%type <val> pictureflags fieldflags posval signed number%type <id> lvalue rvalue typemember value%union { int val; struct xy pos; struct xy size; struct field field; struct event event; struct picture picture; struct id id; struct viewport viewport; struct stmt *stmt; struct ccode ccode; struct literal literal; struct list list;}%%/****************************************************************** * * M O D U L E * ******************************************************************/module: /* Empty */ { $$.viewport = 0; } | module viewport { struct viewport *p = memalloc(sizeof *p); memcpy(p, &$2, sizeof *p); p->link.next = &list.viewport->link; list.viewport = p; } | module picture { struct picture *p = memalloc(sizeof *p); memcpy(p, &$2, sizeof *p); p->link.next = &list.picture->link; list.picture = p; } | module ccode { struct ccode *p = memalloc(sizeof *p); memcpy(p, &$2, sizeof *p); p->link.next = &list.ccode->link; list.ccode = p; } | module GLOBAL event { struct event *p = memalloc(sizeof *p); memcpy(p, &$3, sizeof *p); p->link.next = &list.event->link; list.event = p; p->global = 1; } | module event { struct event *p = memalloc(sizeof *p); memcpy(p, &$2, sizeof *p); p->link.next = &list.event->link; list.event = p; } | module error { error("syntax error"); } ;/****************************************************************** * * V I E W P O R T * ******************************************************************/viewport: VIEWPORT ID LBRACE viewportmembers RBRACE { $$.link.name = strduplicate($2.id); $$.size = $4.size; $$.pos = $4.pos; };viewportmembers: /* Empty */ { $$.pos.x = $$.pos.y = 0; $$.size.x = $$.size.y = 0; } | viewportmembers pos { $$.pos = $2; } | viewportmembers size { $$.size = $2; } ;/****************************************************************** * * P I C T U R E * ******************************************************************/picture: PICTURE ID VIEWPORT ID LBRACE picturemembers RBRACE { struct viewport *vp = (struct viewport *)find_name(&list.viewport->link, $4.id); if (vp == NULL) { error("unknown viewport"); YYERROR; } else { $$.link.name = strduplicate($2.id); $$.field = $6.field; $$.literal = $6.literal; $$.event = $6.event; $$.flags = $6.flags; $$.viewport = vp; } };picturemembers: /* Empty */ { $$.field = NULL; $$.event = NULL; $$.literal = NULL; $$.flags = 0; } | picturemembers field { struct field *p = memalloc(sizeof *p); memcpy(p, &$2, sizeof *p); p->link.next = &$$.field->link; $$.field = p; } | picturemembers event { struct event *p = memalloc(sizeof *p); memcpy(p, &$2, sizeof *p); p->link.next = &$$.event->link; $$.event = p; } | picturemembers literal { struct literal *p = memalloc(sizeof *p); memcpy(p, &$2, sizeof *p); p->link.next = &$$.literal->link; $$.literal = p; } | picturemembers pictureflags { $$.flags |= $2; } ;pictureflags: FRAME SEMI { $$ = PIC_FRAME; } ;/****************************************************************** * * F I E L D * ******************************************************************/field: FIELD ID LBRACE {current.field.flags = 0; } fieldmembers RBRACE { $$.link.next = NULL; $$.link.name = strduplicate($2.id); $$.pos = $5.pos; $$.event = $5.event; $$.lvalue = $5.lvalue; $$.rvalue = $5.rvalue; $$.type = $5.type; $$.value = $5.value; $$.len = $5.len; $$.flags = $5.flags; if ($$.type == NULL) { error("unknown type for field"); if ($$.lvalue) free($$.lvalue); if ($$.rvalue) free($$.rvalue); if ($$.type) free($$.type); if ($$.value) free($$.value); YYERROR; } } ;fieldmembers: /* Empty */ { $$.pos.x = 0; $$.pos.y = 0; $$.event = NULL; $$.lvalue = NULL; $$.rvalue = NULL; $$.type = NULL; $$.value = NULL; $$.len = 0; $$.flags = 0; } | fieldmembers pos { $$.pos = $2; } | fieldmembers event { struct event *p = memalloc(sizeof *p); memcpy(p, &$2, sizeof *p); p->link.next = &$$.event->link; $$.event = p; } | fieldmembers lvalue { $$.lvalue = strip_quotes(strduplicate($2.id)); } | fieldmembers rvalue { $$.rvalue = strip_quotes(strduplicate($2.id)); } | fieldmembers type { $$.type = $2.type ; $$.len = $2.len; } | fieldmembers value { $$.value = strip_quotes(strduplicate($2.id)); } | fieldmembers fieldflags { $$.flags |= $2; } | fieldmembers error SEMI { error("syntax error for field"); yyerrok; } ;fieldflags: PROTECTED SEMI { $$ = FLD_PROTECTED; } | FORBIDDEN SEMI { $$ = FLD_FORBIDDEN; } | UPPERCASE SEMI { $$ = FLD_UPPERCASE; } | HIGHLIGHT SEMI { $$ = FLD_HIGHLIGHT; } | INVISIBLE SEMI { $$ = FLD_INVISIBLE; };lvalue: LVALUE ID SEMI { $$ = $2; };rvalue: RVALUE ID SEMI { $$ = $2; };type: TYPE typemember SEMI { $$.type = strduplicate($2.id); } | TYPE typemember LPAR number RPAR SEMI { $$.type = strduplicate($2.id); $$.len = $4; } ;typemember: CHAR { strcpy($$.id, "FLD_CHAR"); }; | ALNUM { strcpy($$.id, "FLD_ALNUM"); } | INT { strcpy($$.id, "FLD_INT"); }; value: VALUE ID SEMI { $$ = $2; };/****************************************************************** * * L I T E R A L * ******************************************************************/literal: LITERAL xcommay COMMA ID SEMI { $$.link.next = NULL; $$.link.name = strip_quotes(strduplicate($4.id)); $$.pos = $2; $$.flags = 0; } ;/****************************************************************** * * E V E N T * ******************************************************************/event: EVENT eventtype LBRACE stmt RBRACE { $$.link.next = NULL; $$.link.name = $2.link.name; $$.type = $2.type; $$.code = $2.code; $$.global = 0; $$.stmt = $4; } | EVENT eventtype FORGET SEMI { $$.link.next = NULL; $$.link.name = $2.link.name; $$.type = $2.type; $$.code = $2.code; $$.global = 0; $$.stmt = NULL; } | EVENT error { $$.link.next = NULL; $$.stmt = NULL; error("syntax error for event"); };eventtype: /* Empty */ { $$.type = NULL; $$.code = NULL; } | KEY ID { char name[100]; sprintf(name, "key_%s", $2.id); $$.link.name = strtoupper(strduplicate(name)); $$.type = strduplicate("EVENT_KEY"); $$.code = key_lookup($2.id); if ($$.code != NULL) { $$.code = strduplicate($$.code); } else { error("unknown key"); YYERROR; } } | ID { char name[100]; sprintf(name, "EVENT_%s", $1.id); $$.link.name = strtoupper(strduplicate($1.id)); $$.type = strtoupper(strduplicate(name)); $$.code = strduplicate("0"); if (event_lookup($1.id) == NULL) { error("unknown event"); YYERROR; } } ;/****************************************************************** * * C C O D E * ******************************************************************/ccode: CCODE LBRACE stmt RBRACE { $$.link.next = NULL; $$.stmt = $3; } | CCODE error RBRACE { $$.link.next = NULL; $$.stmt = NULL; error(" ccode"); };/****************************************************************** * * Others * ******************************************************************/pos: POS xcommay SEMI { $$ = $2; }xcommay: {last = &last_x;} posval COMMA {last = &last_y;} posval { last_x = $$.x = $2; last_y = $$.y = $5; } ;size: SIZE posval COMMA posval SEMI { $$.x = $2; $$.y = $4; } ;posval: signed | CENTER { $$ = CF_CENTER; } | MAX { $$ = CF_MAX; } ;signed: number {$$ = $1;} | PLUS number {$$ = *last + $2;} | MINUS number {$$ = *last - $2;} ;stmt: { current.stmt = NULL; keywords = 0; $$ = NULL; } intstmt { keywords=1; $$ = current.stmt; } ;intstmt: /* Empty */ { $$ = NULL; } | intstmt ID { stmt_add(¤t.stmt, $2.id, $2.space); } | intstmt LBRACE {stmt_add(¤t.stmt, "{", $2.space);} intstmt RBRACE { stmt_add(¤t.stmt, "}", $5.space); } ;number: NUMBER { $$ = atoi($1.id); };%%static int yylex(void){ static char token[500]; static char space[500];#if YYDEBUG != 0 extern int yydebug; yydebug = 1;#endif if (GetTok(token, space) == NULL) return -1; strcpy(yylval.id.id, token); strcpy(yylval.id.space, space); if (keywords) { if (strequ(token, "VIEWPORT") == 0) return VIEWPORT; if (strequ(token, "CCODE") == 0) return CCODE; if (strequ(token, "PICTURE") == 0) return PICTURE; if (strequ(token, "FIELD") == 0) return FIELD; if (strequ(token, "PROTECTED") == 0) return PROTECTED; if (strequ(token, "FORBIDDEN") == 0) return FORBIDDEN; if (strequ(token, "INVISIBLE") == 0) return INVISIBLE; if (strequ(token, "UPPERCASE") == 0) return UPPERCASE; if (strequ(token, "HIGHLIGHT") == 0) return HIGHLIGHT; if (strequ(token, "FRAME") == 0) return FRAME; if (strequ(token, "VALUE") == 0) return VALUE; if (strequ(token, "LITERAL") == 0) return LITERAL; if (strequ(token, "LVALUE") == 0) return LVALUE; if (strequ(token, "RVALUE") == 0) return RVALUE; if (strequ(token, "EVENT") == 0) return EVENT; if (strequ(token, "KEY") == 0) return KEY; if (strequ(token, "POS") == 0) return POS; if (strequ(token, "CENTER") == 0) return CENTER; if (strequ(token, "MAX") == 0) return MAX; if (strequ(token, "+") == 0) return PLUS; if (strequ(token, "-") == 0) return MINUS; if (strequ(token, "TYPE") == 0) return TYPE; if (strequ(token, "CHAR") == 0) return CHAR; if (strequ(token, "ALNUM") == 0) return ALNUM; if (strequ(token, "SIZE") == 0) return SIZE; if (strequ(token, "GLOBAL") == 0) return GLOBAL; if (strequ(token, "INT") == 0) return INT; if (strequ(token, ",") == 0) return COMMA; if (strequ(token, ";") == 0) return SEMI; if (strequ(token, "(") == 0) return LPAR; if (strequ(token, ")") == 0) return RPAR; if (strequ(token, "KEY") == 0) return KEY; if (strequ(token, "FORGET") == 0) return FORGET; if (isdigit(token[0])) return NUMBER; } if (strequ(token, "{") == 0) return LBRACE; if (strequ(token, "}") == 0) return RBRACE; return ID;}intyyerror(const char *txt){ return 0;}static char *key_lookup(char *key){ static struct { char *key; char *code; } keys[] = {#include "keys.h" }; int i; for (i = 0; i < (sizeof keys / sizeof keys[0]); i++) { if (strequ(keys[i].key, key) == 0) return keys[i].code; } return NULL;}static char *event_lookup(char *event){ static struct { char *event; } events[] = {#include "events.h" }; int i; for (i = 0; i < (sizeof events / sizeof events[0]); i++) { if (strequ(events[i].event, event) == 0) return events[i].event; } return NULL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -