From c89da89b6917a4ca421953a8e4207a74208e3096 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 13 Jun 2001 07:16:39 +0000 Subject: [PATCH] almost parses CustomTF ($macro junk next) --- tools/qfcc/source/qc-lex.l | 141 +++++++++++++++++++++++++++++++++-- tools/qfcc/source/qc-parse.y | 60 ++++++++++----- tools/qfcc/source/qfcc.c | 12 +++ 3 files changed, 188 insertions(+), 25 deletions(-) diff --git a/tools/qfcc/source/qc-lex.l b/tools/qfcc/source/qc-lex.l index 0989c6d52..b991d67fc 100644 --- a/tools/qfcc/source/qc-lex.l +++ b/tools/qfcc/source/qc-lex.l @@ -1,23 +1,83 @@ %{ +#include #include "qfcc.h" #include "qc-parse.h" #define YY_NO_UNPUT +int lineno; + +void error (char*s){} + +int type_or_name (char *token); + +int do_grab (void); + +extern YYSTYPE yylval; + %} DIGIT [0-9] ID [a-zA-Z_][a-zA-Z_0-9]* +FLOAT {DIGIT}+"."{DIGIT}* +NUM ({DIGIT}+("."{DIGIT}*)?) +s [ \t] +m ([\-+]?) %% -{DIGIT}+"."{DIGIT}* return IMMEDIATE; +"/*" { + int c; + do { + while ((c = input ()) != '*' && c != EOF + && c != '\n') + ; + while (c == '*') + c = input (); + if (c == EOF) + error ("EOF in comment"); + if (c == '\n') + lineno++; + } while (c != '/' && c != EOF); + } -{ID} return NAME; +"//".*$ /* nothing to do */ -\"(\.|[^"])*\" +{DIGIT}+ { + yylval.int_val = atoi (yytext); + return INT_VAL; + } -"!"|"("|")"|"{"|"}"|"."|"*"|"/"|"&"|"|"|"+"|"-"|"="|"["|"]" return yytext[0]; +{FLOAT}* { + yylval.float_val = atof (yytext); + return FLOAT_VAL; + } + +{ID} return type_or_name(yytext); + +\"(\\.|[^"])*\" { + //yylval.string_val = strdup (yytext); + return STRING_VAL; + } + +'{s}*{m}{NUM}{s}+{m}{NUM}{s}+{m}{NUM}{s}*' { + sscanf (yytext, "%f %f %f", &yylval.vector_val[0], + &yylval.vector_val[1], + &yylval.vector_val[2]); + return VECTOR_VAL; + } + +'{s}*{m}{NUM}{s}+{m}{NUM}{s}+{m}{NUM}{s}+{m}{NUM}{s}*' { + sscanf (yytext, "%f %f %f %f", &yylval.vector_val[0], + &yylval.vector_val[1], + &yylval.vector_val[2], + &yylval.vector_val[3]); + return VECTOR_VAL; + } + +"!"|"("|")"|"{"|"}"|"."|"*"|"/"|"&"|"|"|"+"|"-"|"="|"["|"]"|"#"|";"|"," return yytext[0]; + +"..." return ELIPSIS; "&&" return AND; "||" return OR; @@ -28,11 +88,18 @@ ID [a-zA-Z_][a-zA-Z_0-9]* "<" return LT; ">" return GT; -^# +"$"{ID} { + int ret = do_grab(); + if (ret) + return ret; + } -\n +^#{s}+{DIGIT}+{s}+\"(\.|[^"])*\".$ { + } -. +\n lineno++; + +. error ("all your typo are belong to us"); %% @@ -41,3 +108,63 @@ yywrap (void) { return 1; } + +typedef struct { + const char *name; + int value; + type_t *type; +} keyword_t; + +static keyword_t keywords[] = { + {"float", TYPE, &type_float }, + {"vector", TYPE, &type_vector}, + {"entity", TYPE, &type_entity}, + {"string", TYPE, &type_string}, + {"void", TYPE, &type_void }, + {"local", LOCAL, 0 }, + {"return", RETURN, 0 }, + {"while", WHILE, 0 }, + {"do", DO, 0 }, + {"if", IF, 0 }, + {"else", ELSE, 0 }, + {"for", FOR, 0 }, +}; + +static const char * +keyword_get_key (void *kw, void *unused) +{ + return ((keyword_t*)kw)->name; +} + +int +type_or_name (char *token) +{ + static int initialized = 0; + static hashtab_t *keyword_tab; + keyword_t *keyword; + + if (!initialized) { + int i; + keyword_tab = Hash_NewTable (1021, keyword_get_key, 0, 0); + for (i = 0; i < sizeof (keywords) / sizeof (keywords[0]); i++) + Hash_Add (keyword_tab, &keywords[i]); + initialized = 1; + } + keyword = Hash_Find (keyword_tab, token); + if (keyword) { + yylval.type = keyword->type; + return keyword->value; + } + return NAME; +} + +int +do_grab (void) +{ + static int initialized; + + if (!initialized) { + initialized = 1; + } + return 0; +} diff --git a/tools/qfcc/source/qc-parse.y b/tools/qfcc/source/qc-parse.y index 75685dbeb..111fbd054 100644 --- a/tools/qfcc/source/qc-parse.y +++ b/tools/qfcc/source/qc-parse.y @@ -1,10 +1,12 @@ %{ #include "qfcc.h" - +#define YYDEBUG 1 +#define YYERROR_VERBOSE 1 void yyerror (char *s) { - fprintf (stderr, "%s\n", s); + extern int lineno; + fprintf (stderr, "%d, %s\n", lineno, s); } int yylex (void); @@ -13,6 +15,12 @@ int yylex (void); %union { def_t *def; + type_t *type; + int int_val; + float float_val; + char *string_val; + float vector_val[3]; + float quaternion_val[4]; } %left OR AND @@ -22,9 +30,9 @@ int yylex (void); %left '*' '/' '&' '|' %left '!' '.' '(' -%token NAME IMMEDIATE +%token NAME INT_VAL FLOAT_VAL STRING_VAL VECTOR_VAL QUATERNION_VAL -%token LOCAL TYPE RETURN WHILE DO IF ELSE FOR +%token LOCAL TYPE RETURN WHILE DO IF ELSE FOR ELIPSIS %expect 1 @@ -36,8 +44,12 @@ defs ; def - : TYPE def_list - | '.' TYPE def_list + : type def_list + ; + +type + : TYPE + | '.' TYPE ; def_list @@ -48,22 +60,24 @@ def_list def_item : NAME opt_initializer | '(' param_list ')' NAME opt_initializer + | '(' ')' NAME opt_initializer + | '(' ELIPSIS ')' NAME opt_initializer ; param_list - : /* emtpy */ + : param | param_list ',' param ; param - : TYPE NAME + : type def_item ; opt_initializer : /*empty*/ - | '=' '#' IMMEDIATE + | '=' '#' const | '=' statement_block - | '=' IMMEDIATE + | '=' const | '=' '[' expr ',' expr ']' statement_block ; @@ -73,21 +87,21 @@ statement_block statements : /*empty*/ - | statements statement ';' + | statements statement ; statement : ';' | statement_block - | RETURN expr - | RETURN + | RETURN expr ';' + | RETURN ';' | WHILE '(' expr ')' statement - | DO statement WHILE '(' expr ')' - | LOCAL def_list + | DO statement WHILE '(' expr ')' ';' + | LOCAL type def_list ';' | IF '(' expr ')' statement | IF '(' expr ')' statement ELSE statement | FOR '(' expr ';' expr ';' expr ')' statement - | expr + | expr ';' ; expr @@ -108,15 +122,25 @@ expr | expr '|' expr | expr '.' expr | expr '(' arg_list ')' + | expr '(' ')' + | '-' expr | '!' expr | NAME - | IMMEDIATE + | const | '(' expr ')' ; arg_list - : /*empty*/ + : expr | arg_list ',' expr ; +const + : FLOAT_VAL + | STRING_VAL + | VECTOR_VAL + | QUATERNION_VAL + | INT_VAL + ; + %% diff --git a/tools/qfcc/source/qfcc.c b/tools/qfcc/source/qfcc.c index 9b1182eba..fcd3d7eca 100644 --- a/tools/qfcc/source/qfcc.c +++ b/tools/qfcc/source/qfcc.c @@ -904,12 +904,24 @@ Options: \n\ // compile all the files while ((src = COM_Parse (src))) { + //extern FILE *yyin; + //int yyparse(void); + //extern int yydebug; + //extern int lineno; + //yydebug = 1; + sprintf (filename, "%s/%s", sourcedir, com_token); printf ("compiling %s\n", filename); LoadFile (filename, (void *) &src2); if (!PR_CompileFile (src2, filename)) + //yyin = fopen (filename, "rt"); + //lineno = 1; + //if (yyparse ()) { + // printf ("%s\n", filename); return 1; + //} + //fclose (yyin); } if (!PR_FinishCompilation ())