summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Pouzenc <ludovic@pouzenc.fr>2010-11-14 22:44:27 +0000
committerLudovic Pouzenc <ludovic@pouzenc.fr>2010-11-14 22:44:27 +0000
commit3c21ae9631695fdc498eca2341f21abb30b27b35 (patch)
tree12b3eddd2aea70f2b0c46bd533cff24d430313d9
parentcaf2d729421aaa7baffef76c5d24ffecc28fb6c2 (diff)
download2010-netlemmings-3c21ae9631695fdc498eca2341f21abb30b27b35.tar.gz
2010-netlemmings-3c21ae9631695fdc498eca2341f21abb30b27b35.tar.bz2
2010-netlemmings-3c21ae9631695fdc498eca2341f21abb30b27b35.zip
Lexer et parser qui avale tous les .ini sans erreurs, parcontre actions vides. Il faudrais rendre générique les idenifiants pour les noms de niveau fun_ tricky_...
git-svn-id: file:///var/svn/2010-netlemmings/trunk@150 077b3477-7977-48bd-8428-443f22f7bfda
-rw-r--r--src/parser/parse_ini.lex61
-rw-r--r--src/parser/parse_ini.yy55
-rw-r--r--src/test/Makefile11
-rw-r--r--src/test/test_lex.c40
-rwxr-xr-xsrc/test/test_lex.sh1
-rw-r--r--src/test/test_parse.c19
-rwxr-xr-xsrc/test/test_parse.sh2
7 files changed, 156 insertions, 33 deletions
diff --git a/src/parser/parse_ini.lex b/src/parser/parse_ini.lex
index 8d68a0a..e577123 100644
--- a/src/parser/parse_ini.lex
+++ b/src/parser/parse_ini.lex
@@ -21,12 +21,14 @@ int string(int tok) {
%option noinput
%option nounput
%option noyywrap
+%option case-insensitive
BLANK [ \t]
NOT_BLANK [^ \t]
-IDENT [a-zA-Z][a-zA-Z0-9_-]*
+ /* IDENT [a-z][a-z0-9_-]* */
+STRCSV [a-z][a-z0-9._-]*
INTEGER "-"?[0-9]+
-INTHEX "0x"[0-9a-f]+
+INTHEX 0x[0-9a-f]+
COMMENT "#"[^\n]*
/*
@@ -44,8 +46,8 @@ COMMENT "#"[^\n]*
<*>\r /* Ignore - http://fr.wikipedia.org/wiki/Fin_de_ligne : CRLF*/
/* Other rules for almost states (but VAL_STR) to ignore blanks and comments */
-<TYPE_STR,TYPE_OTHER,VAL_OTHER>"#"[^\n]*\n { yylineno++; } /* Single line Comment*/
-<TYPE_STR,TYPE_OTHER,VAL_OTHER>{BLANK}* /* Ignore */
+<INITIAL,TYPE_STR,TYPE_OTHER,VAL_OTHER>"#"[^\n]* /* Ignore Single line Comment*/
+<INITIAL,TYPE_STR,TYPE_OTHER,VAL_OTHER>{BLANK}* /* Ignore blanks */
/* Initial state, start condition is 'INITIAL' (implicit), we catch only identifiers here */
"style" { BEGIN(TYPE_STR); return STYLE; }
@@ -53,22 +55,61 @@ COMMENT "#"[^\n]*
"superlemming" { BEGIN(TYPE_OTHER); return SLEM; }
-"bgColor" { BEGIN(TYPE_OTHER); return BGCOLOR; }
+"tiles" { BEGIN(TYPE_OTHER); return TILES; }
+"frames_" { BEGIN(TYPE_OTHER); return FRAMES; }
+"anim_" { BEGIN(TYPE_OTHER); return ANIM; }
+"type_" { BEGIN(TYPE_OTHER); return TYPE; }
+"sound_" { BEGIN(TYPE_OTHER); return SOUND; }
+
+"bgcolor" { BEGIN(TYPE_OTHER); return BGCOLOR; }
"debriscolor" { BEGIN(TYPE_OTHER); return DEBRISCOLOR; }
"particlecolor" { BEGIN(TYPE_OTHER); return PARTICLECOLOR; }
+"releaserate" { BEGIN(TYPE_OTHER); return RELEASERATE; }
+"numlemmings" { BEGIN(TYPE_OTHER); return NUMLEMMINGS; }
+"numtorescue" { BEGIN(TYPE_OTHER); return NUMTORESCUE; }
+"timelimit" { BEGIN(TYPE_OTHER); return TIMELIMIT; }
+"numclimbers" { BEGIN(TYPE_OTHER); return NUMCLIMBERS; }
+"numfloaters" { BEGIN(TYPE_OTHER); return NUMFLOATERS; }
+"numbombers" { BEGIN(TYPE_OTHER); return NUMBOMBERS; }
+"numblockers" { BEGIN(TYPE_OTHER); return NUMBLOCKERS; }
+"numbuilders" { BEGIN(TYPE_OTHER); return NUMBUILDERS; }
+"numbashers" { BEGIN(TYPE_OTHER); return NUMBASHERS; }
+"numminers" { BEGIN(TYPE_OTHER); return NUMMINERS; }
+"numdiggers" { BEGIN(TYPE_OTHER); return NUMDIGGERS; }
+"xpos" { BEGIN(TYPE_OTHER); return XPOS; }
+"object_" { BEGIN(TYPE_OTHER); return OBJECT; }
+"terrain_" { BEGIN(TYPE_OTHER); return TERRAIN; }
+"steel_" { BEGIN(TYPE_OTHER); return STEEL; }
+
+"maxFallDistance" { BEGIN(TYPE_OTHER); return MAXFALLDISTANCE; }
+"codeSeed" { BEGIN(TYPE_OTHER); return CODESEED; }
+"music_" { BEGIN(TYPE_STR); return MUSIC; }
+"level_" { BEGIN(TYPE_OTHER); return LEVEL; }
+"fun_" { BEGIN(TYPE_OTHER); return DIFFICULTY; }
+"tricky_" { BEGIN(TYPE_OTHER); return DIFFICULTY; }
+"taxing_" { BEGIN(TYPE_OTHER); return DIFFICULTY; }
+"mayhem_" { BEGIN(TYPE_OTHER); return DIFFICULTY; }
+"tame_" { BEGIN(TYPE_OTHER); return DIFFICULTY; }
+"wild_" { BEGIN(TYPE_OTHER); return DIFFICULTY; }
+"crazy_" { BEGIN(TYPE_OTHER); return DIFFICULTY; }
+"wicked_" { BEGIN(TYPE_OTHER); return DIFFICULTY; }
+"havoc_" { BEGIN(TYPE_OTHER); return DIFFICULTY; }
+
/* TYPE_* states for catching the '=' token and go in the right state machine for catching values */
<TYPE_STR>"="{BLANK}* { BEGIN(VAL_STR); return AFF; }
<TYPE_OTHER>"=" { BEGIN(VAL_OTHER); return AFF; }
-<VAL_STR>[^\r\n]+ { return string(STR); }
-<VAL_OTHER>{INTEGER} { yylval.num = atoi(yytext); return INT; }
-<VAL_OTHER>{INTHEX} { int res=sscanf(yytext, "0x%x", &yylval.uint32); if(res) return INT; else return LEXERROR; }
-<VAL_OTHER>{IDENT} { return string(IDENT); }
+<TYPE_STR,TYPE_OTHER,VAL_OTHER>{INTEGER} { yylval.num = atoi(yytext); return INT; }
+<VAL_OTHER>{INTHEX} { int res=sscanf(yytext, "0x%x", &yylval.uint32); if(res) return INTHEX; else return LEXERROR; }
+<VAL_OTHER>{STRCSV} { return string(STR); }
<VAL_OTHER>"," { return VIR; }
+<VAL_STR>[^\r\n]+ { return string(STR); }
+
-<*>.+ { /* Everything else is catched here */
+ /*<*>.+ { Everything else is catched here
fprintf(stderr, "LEX : ERROR : unknown sequence '%s'", yytext);
return LEXERROR;
}
+ */
diff --git a/src/parser/parse_ini.yy b/src/parser/parse_ini.yy
index dc9ca28..bd1b5bc 100644
--- a/src/parser/parse_ini.yy
+++ b/src/parser/parse_ini.yy
@@ -9,6 +9,7 @@
extern FILE *yyin;
extern int yylineno;
+extern char *yytext;
int yylex();
void yyerror(struct gameInit *gInit, char *s);
@@ -19,15 +20,14 @@ void yyerror(struct gameInit *gInit, char *s);
%union {char* str; int num; uint32_t uint32; uint32_t *p_uint32;}
-%token LEXERROR
-%token EOL
+%token LEXERROR EOL
-%token STYLE
-%token NAME
-%token SLEM
-%token BGCOLOR
-%token DEBRISCOLOR
-%token PARTICLECOLOR
+%token STYLE NAME SLEM
+%token TILES FRAMES ANIM TYPE SOUND
+%token BGCOLOR DEBRISCOLOR PARTICLECOLOR
+%token XPOS OBJECT TERRAIN STEEL RELEASERATE NUMLEMMINGS NUMTORESCUE TIMELIMIT
+%token NUMCLIMBERS NUMFLOATERS NUMBOMBERS NUMBLOCKERS NUMBUILDERS NUMBASHERS NUMMINERS NUMDIGGERS
+%token MAXFALLDISTANCE CODESEED MUSIC LEVEL DIFFICULTY
%token AFF
%token VIR
@@ -42,17 +42,43 @@ void yyerror(struct gameInit *gInit, char *s);
%start ini
%%
-ini:
-| ini decl
-| ini EOL
+ini: /*epsilon*/
+| decl ini
+| EOL ini
decl: STYLE AFF STR {}
| NAME AFF STR { gInit->mapI.name = $3; }
-| SLEM AFF INT {}
+| SLEM AFF STR {}
+| TILES AFF INT {}
+| FRAMES INT AFF INT {}
+| ANIM INT AFF INT {}
+| TYPE INT AFF INT {}
+| SOUND INT AFF INT {}
| BGCOLOR AFF INTHEX { gInit->mapI.map.cmap.bgColor = $3; }
| DEBRISCOLOR AFF INTHEX { gInit->mapI.map.cmap.debrisColor = $3; }
| PARTICLECOLOR AFF particles { gInit->mapI.map.cmap.particleColor = $3; }
-| IDENT AFF STR {}
+
+| XPOS AFF INT {}
+| OBJECT INT AFF INT VIR INT VIR INT VIR INT VIR INT {}
+| TERRAIN INT AFF INT VIR INT VIR INT VIR INT {}
+| STEEL INT AFF INT VIR INT VIR INT VIR INT {}
+| RELEASERATE AFF INT {}
+| NUMLEMMINGS AFF INT {}
+| NUMTORESCUE AFF INT {}
+| TIMELIMIT AFF INT {}
+| NUMCLIMBERS AFF INT {}
+| NUMFLOATERS AFF INT {}
+| NUMBOMBERS AFF INT {}
+| NUMBLOCKERS AFF INT {}
+| NUMBUILDERS AFF INT {}
+| NUMBASHERS AFF INT {}
+| NUMMINERS AFF INT {}
+| NUMDIGGERS AFF INT {}
+| MAXFALLDISTANCE AFF INT {}
+| CODESEED AFF STR {}
+| MUSIC INT AFF STR {}
+| LEVEL INT AFF STR {}
+| DIFFICULTY INT AFF STR VIR INT {}
particles: INTHEX VIR INTHEX VIR INTHEX VIR INTHEX VIR INTHEX VIR INTHEX VIR INTHEX VIR INTHEX VIR INTHEX VIR INTHEX VIR INTHEX VIR INTHEX VIR INTHEX VIR INTHEX VIR INTHEX VIR INTHEX {
$$=malloc(16*sizeof(uint32_t));
@@ -60,7 +86,8 @@ particles: INTHEX VIR INTHEX VIR INTHEX VIR INTHEX VIR INTHEX VIR INTHEX VIR INT
}
%%
void yyerror(struct gameInit *gInit, char *s) {
- fprintf(stderr, "(stdin):%i: error: %s\n", yylineno, s);
+ fprintf(stderr, "(stdin):%i: error: %s near '%s'\n", yylineno, s, yytext);
gInit->parseError=1;
+ exit(1);
}
diff --git a/src/test/Makefile b/src/test/Makefile
new file mode 100644
index 0000000..1918e8d
--- /dev/null
+++ b/src/test/Makefile
@@ -0,0 +1,11 @@
+all: test_lex test_parse
+
+test_lex: test_lex.c ../parser/lex.yy.c
+ gcc -Wall --std=c99 -D_POSIX_SOURCE -g -o $@ $^
+
+test_parse: test_parse.c ../parser/y.tab.c ../parser/lex.yy.c
+ gcc -Wall --std=c99 -D_POSIX_SOURCE -g -o $@ $^
+
+clean:
+ -rm test_lex test_parse
+
diff --git a/src/test/test_lex.c b/src/test/test_lex.c
new file mode 100644
index 0000000..d936e7b
--- /dev/null
+++ b/src/test/test_lex.c
@@ -0,0 +1,40 @@
+#include <stdio.h>
+#include "SDL/SDL.h"
+#include "../parser/ginit.h"
+
+extern FILE *yyin;
+extern int yylex();
+
+
+typedef union YYSTYPE { char* str; int num; uint32_t uint32; uint32_t *p_uint32; } YYSTYPE;
+
+YYSTYPE yylval;
+
+int main(int argc, char **argv) {
+ char *filepath=NULL;
+ int res;
+
+ if (argc<2) {
+ fprintf(stderr, "Usage %s <ini_file>\n", argv[0]);
+ return 1;
+ }
+ filepath=argv[1];
+
+ if ( strcmp(argv[1], "-") == 0 ) {
+ yyin=stdin;
+ } else {
+ yyin=fopen(filepath, "r");
+ if (yyin == NULL ) {
+ fprintf(stderr, "main(), Could not open '%s'\n", filepath);
+ return 2;
+ }
+ }
+ printf("Parsing '%s'\n", filepath);
+ while( (res=yylex()) ) {
+ fprintf(stderr, "%i\n", res);
+ }
+ printf("\nEnd of parse ('%s')\n", filepath);
+
+ fclose(yyin);
+ return 0;
+}
diff --git a/src/test/test_lex.sh b/src/test/test_lex.sh
new file mode 100755
index 0000000..452f29f
--- /dev/null
+++ b/src/test/test_lex.sh
@@ -0,0 +1 @@
+(cd ../parser/ && make) && make && find ../../styles/ ../../level/ -name *.ini -exec ./test_lex {} \; 2>/dev/null | less
diff --git a/src/test/test_parse.c b/src/test/test_parse.c
index ed7987d..4b65eb8 100644
--- a/src/test/test_parse.c
+++ b/src/test/test_parse.c
@@ -8,7 +8,7 @@ extern int yyparse(struct gameInit *gInit);
int main(int argc, char **argv) {
char *filepath=NULL;
- struct gameInit *gInit=NULL;
+ struct gameInit gInit;
if (argc<2) {
fprintf(stderr, "Usage %s <ini_file>\n", argv[0]);
@@ -16,15 +16,18 @@ int main(int argc, char **argv) {
}
filepath=argv[1];
- yyin=fopen(filepath, "r");
- if (yyin == NULL ) {
- fprintf(stderr, "main(), Could not open '%s'\n", filepath);
- return 2;
+ if ( strcmp(argv[1], "-") == 0 ) {
+ yyin=stdin;
+ } else {
+ yyin=fopen(filepath, "r");
+ if (yyin == NULL ) {
+ fprintf(stderr, "main(), Could not open '%s'\n", filepath);
+ return 2;
+ }
}
-
printf("Parsing '%s'\n", filepath);
- yyparse(gInit);
- printf("End of parse ('%s')\n", filepath);
+ yyparse(&gInit);
+// printf("End of parse ('%s')\n", filepath);
fclose(yyin);
return 0;
diff --git a/src/test/test_parse.sh b/src/test/test_parse.sh
index 4cc8323..07fa640 100755
--- a/src/test/test_parse.sh
+++ b/src/test/test_parse.sh
@@ -1 +1 @@
-gcc -Wall --std=c99 -D_POSIX_SOURCE -g test_parse.c ../parser/y.tab.c ../parser/lex.yy.c
+(cd ../parser/ && make) && make && find ../../styles/ ../../level/ -name *.ini -exec ./test_parse {} \; 2>&1 | less