浏览代码

lolfx: preprocessor support in the LolFx parser. But this shit is going

nowhere, we’re probably gonna ditch the approach in favour of a GLSL to
HLSL translator instead.
legacy
Sam Hocevar sam 11 年前
父节点
当前提交
a490c8c4c7
共有 6 个文件被更改,包括 3889 次插入3382 次删除
  1. +1713
    -1616
      src/generated/lolfx-parser.cpp
  2. +1981
    -1748
      src/generated/lolfx-scanner.cpp
  3. +1
    -0
      src/gpu/lolfx-compiler.cpp
  4. +12
    -0
      src/gpu/lolfx-compiler.h
  5. +5
    -4
      src/gpu/lolfx-parser.y
  6. +177
    -14
      src/gpu/lolfx-scanner.l

+ 1713
- 1616
src/generated/lolfx-parser.cpp
文件差异内容过多而无法显示
查看文件


+ 1981
- 1748
src/generated/lolfx-scanner.cpp
文件差异内容过多而无法显示
查看文件


+ 1
- 0
src/gpu/lolfx-compiler.cpp 查看文件

@@ -30,6 +30,7 @@ bool LolFxCompiler::ParseString(char const *command)
LolFxScanner scanner(command);
m_lexer = &scanner;
LolFxParser parser(*this);
//parser.set_debug_level(1);
if (parser.parse() != 0)
return false;
return true;


+ 12
- 0
src/gpu/lolfx-compiler.h 查看文件

@@ -36,6 +36,18 @@ public:
LolFxParser::location_type* yylloc);

private:
bool IsExpressionTrue(char const *buf);

Map<String, String> m_pp_defines;

enum
{
BlockIsFalse,
BlockIsForeverFalse,
BlockIsTrue,
};
Array<int> m_pp_stack;

char const *m_input;
};



+ 5
- 4
src/gpu/lolfx-parser.y 查看文件

@@ -347,6 +347,10 @@ group_glsl_type:
| GT_USAMPLERCUBE
| GT_USAMPLERCUBEARRAY
| GT_USAMPLERBUFFER
| HGT_SAMPLER1D
| HGT_SAMPLER2D
| HGT_SAMPLER3D
| HGT_SAMPLERCUBE
;

group_glsl_keyword_in_hlsl:
@@ -403,10 +407,6 @@ group_hlsl_keyword_in_glsl:
| HGT_NOPERSPECTIVE
| HGT_OUT
| HGT_RETURN
| HGT_SAMPLER1D
| HGT_SAMPLER2D
| HGT_SAMPLER3D
| HGT_SAMPLERCUBE
| HGT_STRUCT
| HGT_SWITCH
| HGT_UINT
@@ -712,6 +712,7 @@ group_language_symbols:

lolfx_file:
lolfx_section_list
T_END
;

lolfx_section_list:


+ 177
- 14
src/gpu/lolfx-scanner.l 查看文件

@@ -42,6 +42,7 @@ typedef lol::LolFxParser::token_type token_type;

%x C_COMMENT
%x CPP_COMMENT
%x PREPROCESSOR_COMMENT

%%

@@ -50,6 +51,7 @@ typedef lol::LolFxParser::token_type token_type;
yylloc->step();

int language_guess = INITIAL;
m_pp_stack.Push(BlockIsTrue);
%}

/*
@@ -466,24 +468,174 @@ typedef lol::LolFxParser::token_type token_type;
* Gathered from http://msdn.microsoft.com/en-us/library/windows/desktop/bb943993%28v=vs.85%29.aspx
*/

"#"[ \t]*"define" { return token::PREPROCESSOR_DEFINE; }
"#"[ \t]*"elif" { return token::PREPROCESSOR_ELIF; }
"#"[ \t]*"else" { return token::PREPROCESSOR_ELSE; }
"#"[ \t]*"endif" { return token::PREPROCESSOR_ENDIF; }
"#"[ \t]*"error" { return token::PREPROCESSOR_ERROR; }
"#"[ \t]*"if" { return token::PREPROCESSOR_IF; }
"#"[ \t]*"ifdef" { return token::PREPROCESSOR_IFDEF; }
"#"[ \t]*"ifndef" { return token::PREPROCESSOR_IFNDEF; }
"#"[ \t]*"include" { return token::PREPROCESSOR_INCLUDE; }
"#"[ \t]*"line" { return token::PREPROCESSOR_LINE; }
"#"[ \t]*"pragma" { return token::PREPROCESSOR_PRAGMA; }
"#"[ \t]*"undef" { return token::PREPROCESSOR_UNDEF; }
^[ \t]*"#"[ \t]*"define".* {
/* FIXME: this is very, very limited */
char const *tmp = strstr(yytext, "define") + 6;
while (*tmp == ' ' || *tmp == '\n')
tmp++;
if (*tmp == '\0')
return token::PREPROCESSOR_DEFINE;
char const *tmp2 = tmp;
while (*tmp != ' ' && *tmp != '\n' && *tmp != '\0')
tmp++;
String key(tmp2, (int)(tmp - tmp2));
while (*tmp == ' ' || *tmp == '\n')
tmp++;
String val(*tmp ? tmp : "1");

Log::Debug("new macro: ‘%s’ = ‘%s’\n", key.C(), val.C());
m_pp_defines[key] = val;
}

^[ \t]*"#"[ \t]*"elif" {
if (m_pp_stack.Count() <= 1)
return token::PREPROCESSOR_ELIF;
m_pp_stack.Last() = BlockIsForeverFalse;
BEGIN(PREPROCESSOR_COMMENT);
}

^[ \t]*"#"[ \t]*"else" {
if (m_pp_stack.Count() <= 1)
return token::PREPROCESSOR_ELSE;
m_pp_stack.Last() = BlockIsForeverFalse;
BEGIN(PREPROCESSOR_COMMENT);
}

^[ \t]*"#"[ \t]*"endif" {
if (m_pp_stack.Count() <= 1)
return token::PREPROCESSOR_ENDIF;
m_pp_stack.Pop();
}

^[ \t]*"#"[ \t]*"error".* { return token::PREPROCESSOR_ERROR; }

^[ \t]*"#"[ \t]*"if".* {
if (IsExpressionTrue(strstr(yytext, "if") + 2))
{
m_pp_stack.Push(BlockIsTrue);
}
else
{
m_pp_stack.Push(BlockIsFalse);
BEGIN(PREPROCESSOR_COMMENT);
}
}

^[ \t]*"#"[ \t]*"ifdef" {
/* FIXME: this is very, very limited */
char const *tmp = strstr(yytext, "ifdef") + 5;
while (*tmp == ' ' || *tmp == '\n')
tmp++;
if (*tmp == '\0')
return token::PREPROCESSOR_IFDEF;
char const *tmp2 = tmp;
while (*tmp != ' ' && *tmp != '\n' && *tmp != '\0')
tmp++;
String key(tmp2, (int)(tmp - tmp2));
if (m_pp_defines.HasKey(key))
{
m_pp_stack.Push(BlockIsTrue);
}
else
{
m_pp_stack.Push(BlockIsFalse);
BEGIN(PREPROCESSOR_COMMENT);
}
}

^[ \t]*"#"[ \t]*"ifndef" {
/* FIXME: this is very, very limited */
char const *tmp = strstr(yytext, "ifndef") + 6;
while (*tmp == ' ' || *tmp == '\n')
tmp++;
if (*tmp == '\0')
return token::PREPROCESSOR_IFDEF;
char const *tmp2 = tmp;
while (*tmp != ' ' && *tmp != '\n' && *tmp != '\0')
tmp++;
String key(tmp2, (int)(tmp - tmp2));
if (m_pp_defines.HasKey(key))
{
m_pp_stack.Push(BlockIsFalse);
BEGIN(PREPROCESSOR_COMMENT);
}
else
{
m_pp_stack.Push(BlockIsTrue);
}
}

^[ \t]*"#"[ \t]*"include" { return token::PREPROCESSOR_INCLUDE; }

^[ \t]*"#"[ \t]*"line".* { /* ignore for now */ }

^[ \t]*"#"[ \t]*"pragma".* { /* ignore for now */ }

^[ \t]*"#"[ \t]*"undef" {
/* FIXME: this is very, very limited */
char const *tmp = strstr(yytext, "undef") + 5;
while (*tmp == ' ' || *tmp == '\n')
tmp++;
if (*tmp == '\0')
return token::PREPROCESSOR_UNDEF;
char const *tmp2 = tmp;
while (*tmp != ' ' && *tmp != '\n' && *tmp != '\0')
tmp++;
String key(tmp2, (int)(tmp - tmp2));

Log::Debug("undef macro: ‘%s’\n", key.C());
m_pp_defines.Remove(key);
}

<PREPROCESSOR_COMMENT>^[ \t]*"#"[ \t]*(if|ifdef|ifndef)[ \t]+.*$ {
m_pp_stack.Push(BlockIsForeverFalse);
}
<PREPROCESSOR_COMMENT>^[ \t]*"#"[ \t]*"else" {
switch (m_pp_stack.Last())
{
case BlockIsFalse:
m_pp_stack.Last() = BlockIsTrue;
BEGIN(INITIAL);
break;
case BlockIsForeverFalse:
break;
case BlockIsTrue:
m_pp_stack.Last() = BlockIsForeverFalse;
break;
}
}
<PREPROCESSOR_COMMENT>^[ \t]*"#"[ \t]*"elif" {
switch (m_pp_stack.Last())
{
case BlockIsFalse:
if (IsExpressionTrue(strstr(yytext, "elif") + 4))
{
m_pp_stack.Last() = BlockIsTrue;
BEGIN(INITIAL);
}
break;
case BlockIsForeverFalse:
break;
case BlockIsTrue:
m_pp_stack.Last() = BlockIsForeverFalse;
break;
}
}
<PREPROCESSOR_COMMENT>^[ \t]*"#"[ \t]*"endif" {
m_pp_stack.Pop();
if (m_pp_stack.Last() == BlockIsTrue)
BEGIN(INITIAL);
}
<PREPROCESSOR_COMMENT>\n { yylloc->lines(1); }
<PREPROCESSOR_COMMENT>[^/#]* { }
<PREPROCESSOR_COMMENT>"/*" { BEGIN(C_COMMENT); }
<PREPROCESSOR_COMMENT>[/#] { }

/*
* GLSL preprocessor directives
*/

"#"[ \t]*"version".* { /* ignore for now */ }
^[ \t]*"#"[ \t]*"version"[^\n]* { /* ignore for now */ }

/*
* HLSL reserved keywords
@@ -584,10 +736,15 @@ typedef lol::LolFxParser::token_type token_type;
*/

"/*" { BEGIN(C_COMMENT); }
<C_COMMENT>"*/" { BEGIN(INITIAL); }
<C_COMMENT>[^*\n]* { }
<C_COMMENT>\n { yylloc->lines(1); }
<C_COMMENT>. { }
<C_COMMENT>"*/" {
if (m_pp_stack.Last() == BlockIsTrue)
BEGIN(INITIAL);
else
BEGIN(PREPROCESSOR_COMMENT);
}

/*
* Ignore C++ comments
@@ -617,6 +774,12 @@ int lol::LolFxScanner::LexerInput(char* buf, int max_size)
return buf[0] ? 1 : 0;
}

bool lol::LolFxScanner::IsExpressionTrue(char const *buf)
{
/* FIXME: this is really too limited */
return atoi(buf) != 0;
}

#ifdef yylex
#undef yylex
#endif


正在加载...
取消
保存