mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-31 05:00:35 +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 "qfcc.h"
|
||||||
#include "qc-parse.h"
|
#include "qc-parse.h"
|
||||||
|
|
||||||
#define YY_NO_UNPUT
|
#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]
|
DIGIT [0-9]
|
||||||
ID [a-zA-Z_][a-zA-Z_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 AND;
|
||||||
"||" return OR;
|
"||" return OR;
|
||||||
|
@ -28,11 +88,18 @@ ID [a-zA-Z_][a-zA-Z_0-9]*
|
||||||
"<" return LT;
|
"<" return LT;
|
||||||
">" return GT;
|
">" 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;
|
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"
|
#include "qfcc.h"
|
||||||
|
#define YYDEBUG 1
|
||||||
|
#define YYERROR_VERBOSE 1
|
||||||
void
|
void
|
||||||
yyerror (char *s)
|
yyerror (char *s)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "%s\n", s);
|
extern int lineno;
|
||||||
|
fprintf (stderr, "%d, %s\n", lineno, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
int yylex (void);
|
int yylex (void);
|
||||||
|
@ -13,6 +15,12 @@ int yylex (void);
|
||||||
|
|
||||||
%union {
|
%union {
|
||||||
def_t *def;
|
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
|
%left OR AND
|
||||||
|
@ -22,9 +30,9 @@ int yylex (void);
|
||||||
%left '*' '/' '&' '|'
|
%left '*' '/' '&' '|'
|
||||||
%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
|
%expect 1
|
||||||
|
|
||||||
|
@ -36,8 +44,12 @@ defs
|
||||||
;
|
;
|
||||||
|
|
||||||
def
|
def
|
||||||
: TYPE def_list
|
: type def_list
|
||||||
| '.' TYPE def_list
|
;
|
||||||
|
|
||||||
|
type
|
||||||
|
: TYPE
|
||||||
|
| '.' TYPE
|
||||||
;
|
;
|
||||||
|
|
||||||
def_list
|
def_list
|
||||||
|
@ -48,22 +60,24 @@ def_list
|
||||||
def_item
|
def_item
|
||||||
: NAME opt_initializer
|
: NAME opt_initializer
|
||||||
| '(' param_list ')' NAME opt_initializer
|
| '(' param_list ')' NAME opt_initializer
|
||||||
|
| '(' ')' NAME opt_initializer
|
||||||
|
| '(' ELIPSIS ')' NAME opt_initializer
|
||||||
;
|
;
|
||||||
|
|
||||||
param_list
|
param_list
|
||||||
: /* emtpy */
|
: param
|
||||||
| param_list ',' param
|
| param_list ',' param
|
||||||
;
|
;
|
||||||
|
|
||||||
param
|
param
|
||||||
: TYPE NAME
|
: type def_item
|
||||||
;
|
;
|
||||||
|
|
||||||
opt_initializer
|
opt_initializer
|
||||||
: /*empty*/
|
: /*empty*/
|
||||||
| '=' '#' IMMEDIATE
|
| '=' '#' const
|
||||||
| '=' statement_block
|
| '=' statement_block
|
||||||
| '=' IMMEDIATE
|
| '=' const
|
||||||
| '=' '[' expr ',' expr ']' statement_block
|
| '=' '[' expr ',' expr ']' statement_block
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -73,21 +87,21 @@ statement_block
|
||||||
|
|
||||||
statements
|
statements
|
||||||
: /*empty*/
|
: /*empty*/
|
||||||
| statements statement ';'
|
| statements statement
|
||||||
;
|
;
|
||||||
|
|
||||||
statement
|
statement
|
||||||
: ';'
|
: ';'
|
||||||
| statement_block
|
| statement_block
|
||||||
| RETURN expr
|
| RETURN expr ';'
|
||||||
| RETURN
|
| RETURN ';'
|
||||||
| WHILE '(' expr ')' statement
|
| WHILE '(' expr ')' statement
|
||||||
| DO statement WHILE '(' expr ')'
|
| DO statement WHILE '(' expr ')' ';'
|
||||||
| LOCAL def_list
|
| LOCAL type def_list ';'
|
||||||
| IF '(' expr ')' statement
|
| IF '(' expr ')' statement
|
||||||
| IF '(' expr ')' statement ELSE statement
|
| IF '(' expr ')' statement ELSE statement
|
||||||
| FOR '(' expr ';' expr ';' expr ')' statement
|
| FOR '(' expr ';' expr ';' expr ')' statement
|
||||||
| expr
|
| expr ';'
|
||||||
;
|
;
|
||||||
|
|
||||||
expr
|
expr
|
||||||
|
@ -108,15 +122,25 @@ expr
|
||||||
| expr '|' expr
|
| expr '|' expr
|
||||||
| expr '.' expr
|
| expr '.' expr
|
||||||
| expr '(' arg_list ')'
|
| expr '(' arg_list ')'
|
||||||
|
| expr '(' ')'
|
||||||
|
| '-' expr
|
||||||
| '!' expr
|
| '!' expr
|
||||||
| NAME
|
| NAME
|
||||||
| IMMEDIATE
|
| const
|
||||||
| '(' expr ')'
|
| '(' expr ')'
|
||||||
;
|
;
|
||||||
|
|
||||||
arg_list
|
arg_list
|
||||||
: /*empty*/
|
: expr
|
||||||
| arg_list ',' 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
|
// compile all the files
|
||||||
while ((src = COM_Parse (src))) {
|
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);
|
sprintf (filename, "%s/%s", sourcedir, com_token);
|
||||||
printf ("compiling %s\n", filename);
|
printf ("compiling %s\n", filename);
|
||||||
LoadFile (filename, (void *) &src2);
|
LoadFile (filename, (void *) &src2);
|
||||||
|
|
||||||
if (!PR_CompileFile (src2, filename))
|
if (!PR_CompileFile (src2, filename))
|
||||||
|
//yyin = fopen (filename, "rt");
|
||||||
|
//lineno = 1;
|
||||||
|
//if (yyparse ()) {
|
||||||
|
// printf ("%s\n", filename);
|
||||||
return 1;
|
return 1;
|
||||||
|
//}
|
||||||
|
//fclose (yyin);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!PR_FinishCompilation ())
|
if (!PR_FinishCompilation ())
|
||||||
|
|
Loading…
Reference in a new issue