mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-18 15:01:41 +00:00
almost parses CustomTF ($macro junk next)
This commit is contained in:
parent
a3d2d83e18
commit
c89da89b69
3 changed files with 188 additions and 25 deletions
|
@ -1,23 +1,83 @@
|
|||
%{
|
||||
#include <QF/hash.h>
|
||||
#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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
;
|
||||
|
||||
%%
|
||||
|
|
|
@ -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 ())
|
||||
|
|
Loading…
Reference in a new issue