Browse Source

test: start working on a lexer/parser for LolFx using flex and bison.

legacy
Sam Hocevar sam 12 years ago
parent
commit
1246eb233f
5 changed files with 293 additions and 0 deletions
  1. +4
    -0
      test/sandbox/lex/.gitignore
  2. +10
    -0
      test/sandbox/lex/Makefile
  3. +50
    -0
      test/sandbox/lex/lolfx.l
  4. +126
    -0
      test/sandbox/lex/lolfx.y
  5. +103
    -0
      test/sandbox/lex/test.lolfx

+ 4
- 0
test/sandbox/lex/.gitignore View File

@@ -0,0 +1,4 @@
lex.yy.c
lolfx.tab.c
lolfx.tab.h
parser

+ 10
- 0
test/sandbox/lex/Makefile View File

@@ -0,0 +1,10 @@

parser: lex.yy.c lolfx.tab.c
$(CXX) $^ -o $@ -lfl

lolfx.tab.c: lolfx.y
bison -d $^

lex.yy.c: lolfx.l
flex -d $^


+ 50
- 0
test/sandbox/lex/lolfx.l View File

@@ -0,0 +1,50 @@
%{
#include <iostream>
#define YY_DECL extern "C" int yylex()
#include "lolfx.tab.h"
%}

%x C_COMMENT
%x CPP_COMMENT

%%

/*
* Our language's keywords
*/

"technique" { return TECHNIQUE; }
"pass" { return PASS; }

/*
* Various tokens
*/

[0-9]+\.[0-9]+ { yylval.fval = atof(yytext); return FLOAT; }
[0-9]+ { yylval.ival = atoi(yytext); return INT; }
[a-zA-Z][a-zA-Z0-9_]* {
/* Copy token for now */
yylval.sval = strdup(yytext);
return NAME;
}
[ \t\n]+ ;
. { return *yytext; }

/*
* Ignore C comments
*/

"/*" { BEGIN(C_COMMENT); }
<C_COMMENT>"*/" { BEGIN(INITIAL); }
<C_COMMENT>[^*]* { }
<C_COMMENT>. { }

/*
* Ignore C++ comments
*/

"//" { BEGIN(CPP_COMMENT); }
<CPP_COMMENT>.*\n { BEGIN(INITIAL); }

%%


+ 126
- 0
test/sandbox/lex/lolfx.y View File

@@ -0,0 +1,126 @@
%{
#include <cstdio>
#include <iostream>

extern "C" int yylex();
extern "C" int yyparse();
extern "C" FILE *yyin;
extern "C" int yylineno;

void yyerror(const char *s);
%}

/* The classic Bison union trick */
%union
{
int ival;
float fval;
char *sval;
}

/*
* All the LolFx tokens
*/

%token TECHNIQUE PASS
%token <ival> INT
%token <fval> FLOAT
%token <sval> STRING NAME

%%

fx:
section_list
;

section_list:
section
| section_list section
;

section:
technique
| shader
;

/*
* Grammar for techniques
*/

technique:
TECHNIQUE NAME '{' pass_list '}' { std::cout << "TECHNIQUE" << std::endl; }
;

/*
* Grammar for passes
*/

pass_list:
pass
| pass_list pass
;

pass:
PASS NAME '{' pass_stmt_list '}' { std::cout << "PASS" << std::endl; }
;

pass_stmt_list:
pass_stmt
| pass_stmt_list pass_stmt
;

pass_stmt:
';'
| NAME '=' NAME ';'
| NAME '=' INT ';'
| NAME '[' INT ']' '=' NAME ';'
| NAME '[' INT ']' '=' INT ';'
;

/*
* Grammar for shaders
*/

shader:
shader_region shader_code
| shader_region
;

shader_region:
'#' NAME shader_name { std::cout << "new shader " << $2 << std::endl; }
;

shader_name:
NAME
| shader_name '.' NAME
;

shader_code:
INT shader_code { std::cout << "int: " << $1 << std::endl; }
| FLOAT shader_code { std::cout << "float: " << $1 << std::endl; }
| STRING shader_code { std::cout << "string: " << $1 << std::endl; }
| INT { std::cout << "int: " << $1 << std::endl; }
| FLOAT { std::cout << "float: " << $1 << std::endl; }
| STRING { std::cout << "string: " << $1 << std::endl; }
;

%%

main()
{
yyin = fopen("test.lolfx", "r");
do
{
yyparse();
}
while (!feof(yyin));

fclose(yyin);
}

void yyerror(const char *s)
{
std::cout << "Parse error line " << yylineno << ": " << s << std::endl;
exit(-1);
}


+ 103
- 0
test/sandbox/lex/test.lolfx View File

@@ -0,0 +1,103 @@
/*
* LolFx Test Material
*/

// Can have lots of different techniques in a single lolfx file,
// especially if they share common shader code.
technique Foo
{
// Multiple passes, with alpha on/off, with various blending methods,
// with depth test disabled...
pass p0
{
texture[0] = null;
texture[1] = null;
texture[2] = null;

cullmode = none; // ccw
lighting = false;
zenable = true; // false
alphablendenable = true; // false
srcblend = src_alpha; // one
destblend = inv_src_alpha;

colorop[0] = select_arg1;
colorarg1[0] = diffuse;

alphaop[0] = select_arg1;
alphaarg1[0] = diffuse;

colorop[1] = disable;

alphaop[1] = disable;

// Ye old way
vertexshader = blah;
geometryshader = blah;
pixelshader = blah;

// Ogre crap

// The D3D11 way, but we must make it work with GLSL too
//SetBlendState(AdditiveBlending, float4(0.0f, 0.0f, 0.0f, 0.0f), 0xFFFFFFFF);
//SetDepthStencilState(DisableDepth, 0);
//SetRasterizerState()

//SetVertexShader
//SetDomainShader
//SetHullShader
//SetGeometryShader
//SetPixelShader
//SetComputeShader /* WTF? */

//SetRenderTargets(RTV0, DSV);
//SetRenderTargets(RTV0, RTV1, DSV);
//...
//SetRenderTargets(RTV0, RTV1, RTV2, RTV3, RTV4, RTV5, RTV6, RTV7, DSV);
}

pass p1
{
// Autres vertex/pixel shaders avec éventuellement des
// dépendances sur le résultat des passes précédentes
vertexshader = something_else;
}
}

/* Defines GLSL shader "Prout" */

#section GLSL.Prout

#version 120

/* Valid with my GLSL compiler */
#pragma lolfx semantic(in_Vertex, POSITION)
#pragma lolfx semantic(in_Normal, NORMAL)
#pragma lolfx semantic(in_Color, COLOR)
attribute vec3 in_Vertex;
attribute vec3 in_Normal;
attribute vec4 in_Color;

void main(void)
{
...
}

/* Defines GLSL shader "Zob" */

#section GLSL.Zob

void main(void)
{
shit fuck fuck shit;
}

/* Defines HLSL shader "Prout" */

#section HLSL.Prout

void main(void)
{
/* Blah */
}


Loading…
Cancel
Save