gpt4 book ai didi

c++ - 在 Flex/Bison 中嵌入其他语言

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:36:06 26 4
gpt4 key购买 nike

底线:

如果您想使用 Flex/Bison 在 C++ 中添加一个非常小的功能,您会怎么做?例如,能够使用以下语法声明 void xxx() 函数:foo%%: xxx?

整个故事:

一旦我编写了一个自定义着色器处理程序,该程序从多个 block 构建了现成可用的 Cg/GLSL 像素和顶点着色器。我添加了一些功能,主要与静态编译有关(类似于“更好的预处理器”)。

例如,看起来像

#if LIGHT_TYPE == POINT
float lightStrength = dot(N, normalize(pos - lightPos));
#elif LIGHT_TYPE == DIRECTIONAL
float lightStrength = dot(N, lightDir);
#endif

用纯宏,看起来像

[LightType = Point]
[Require: pos, lightPos]
float LightStrength()
{
!let %N Normal
return dot(%N, normalize(pos - lightPos));
}

用我的“语言”。如您所见,可以为可变光/ Material 类型提供“功能”。还可以“调用”其他函数并标记特定着色器需要哪些统一/可变属性。

为什么要这么努力?因为(特别是在像 SM 2.0 这样的早期卡中)属性有很多限制,而我的“编译器”生成了现成的着色器,其中包含所需的属性/变量列表,像素和顶点着色器之间的托管参数,优化了一些静态内容(只是为了可读性,因为 Cg 编译器稍后会对其进行优化)。

好吧,但我写下所有这些并不是为了赞美自己或其他什么。

我用 C# 编写了这个“编译器”,它最初是一个非常小的程序。但是随着时间的流逝,添加了许多功能,现在该程序一团糟,没有重构的选项。此外,使用 C# 编码意味着我无法将此编译器直接嵌入到 C++ 游戏中,这迫使我生成进程来编译着色器(这需要很多时间)。

我想使用 C++ 和 Flex/Bison 工具包重写我的语言/编译器。我已经在 Flex/Bison 中编写了高效的数学解析器,所以我在这方面有点经验。但是,有一件事我自己无法解决,这是我的问题所在。

我怎样才能将 GLSL 嵌入到我的语言中?在 C# 编译器中,我只是逐行检查行是否以特殊字符(如 % 或 [)开头,然后使用 string_replace 和/或正则表达式做了很多技巧和技巧。

现在我想写下一个干净的 Bison 语法并正确地做它。但是包括 GLSL 的整个语法让我害怕。它是一门庞大而复杂的语言,不断发展。我最想做的就是传递所有这些 GLSL 代码。

如果您完全没有 GLSL/Cg/图形编程经验,那么这不是很重要。问题可以改写成“底线”。

那么,如果您想使用 Flex/Bison 向 C++ 添加一个非常小的功能,您会怎么做?例如,能够使用以下语法声明 void xxx() 函数:foo%%: xxx?

最佳答案

我曾经为一个学校项目向 pascal 添加了多线程机制,所以我不得不处理这个问题。我所做的是我找到了 pascal 的 BNF 定义并复制了它,主要是让我的标记在 99% 的情况下等于文本,并在我添加的 1% 的新标记中添加新的中间语言代码。 Pascal 很简单,所以 BNF 定义相对简单。 C++,没那么多。

Stroustroup 的 C++ 编程语言具有实际上可用于解析器的语言语法,但需要手动复制大量代码。也许是 certain website可以帮助您找到“标准”C++ 的 bison/lex 集,然后您可以对其进行修改。

编辑:我找到了我的 yacc 文件,所以这是我的 pascal 代码的一个小例子

procheader: PROCEDURE ID paramslist ';'{thread::inLocalDecl=true; $$="procedure "+$2+$3+";\n";}
| FUNCTION ID paramslist ':' ID ';'{thread::inLocalDecl=true; $$="function "+$2+$3+":"+$5+";\n";}
| THREAD {thread::inThreadDecl=true;
thread::inArgDecl=true;}
ID {thread::curName=$3;} paramslist { thread::inArgDecl=false;} ';'
{
/*a lot of code to transform this custom construct into standard pascal*/
}

前两个元素只是标准的 pascal:我将输入标记逐字复制到输出字符串中(即我实际上没有修改输入文件中的任何内容)。

第三个元素(我的 THREAD 关键字)显然不是标准的 pascal。所以我将输出转换成我可以用标准 Pascal 编译的东西。

基本上为了编译我的“线程”pascal,我必须获取我的源文件,将它传递给我的解析器,然后编译输出。

关于c++ - 在 Flex/Bison 中嵌入其他语言,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4168175/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com