2010-11-12 4 views
2

La ligne de fond:Intégration autre langue dans Flex/Bison

Si vous souhaitez ajouter un, caractéristique très faible en C++ en utilisant Flex/Bison, comment voulez-vous faire? Par exemple, possibilité de déclarer les fonctions void xxx() avec la syntaxe: foo%%: xxx?

L'histoire:

Une fois que je l'ai codé un programme de traitement de shader personnalisé construit shaders prêt à utiliser Seizième/pixel GLSL et vertex à partir d'un certain nombre de blocs. J'ai ajouté quelques fonctionnalités, principalement liées à la compilation statique (quelque chose comme un "meilleur préprocesseur").

Par exemple, quelque chose qui ressemblerait à

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

avec des macros pures, ressemble

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

dans ma "langue". Comme vous pouvez le voir, des "fonctions" peuvent être fournies pour les types de lumière/matériaux variables. Il existe également une possibilité d '"appeler" une autre fonction et de marquer quels attributs uniformes/variables sont requis pour un shader spécifique.

Pourquoi tous ces efforts? Parce que (surtout dans les premières cartes comme SM 2.0) il y avait de nombreuses limitations d'attributs, et mon "compilateur" produisait un shader prêt à l'emploi avec une liste d'attributs/variables, des paramètres gérés entre pixel et vertex shaders, juste pour la lisibilité, car le compilateur Cg l'optimiserait plus tard de toute façon). OK, mais je n'écris pas tout cela pour me féliciter ou quelque chose.

J'ai écrit ce "compilateur" en C# et c'était initialement un très petit programme. Mais au fil du temps, de nombreuses fonctionnalités ont été ajoutées et maintenant le programme est un désordre complet sans options de refactoring. De plus, étant codé en C#, je ne peux pas intégrer ce compilateur directement dans un jeu C++, ce qui me force à lancer des processus pour compiler des shaders (cela prend beaucoup de temps).

Je voudrais réécrire mon langage/compilateur en utilisant C++ et Flex/Bison toolkit. J'ai déjà codé un analyseur mathématique efficace dans Flex/Bison, donc je suis assez expérimenté dans ce domaine. Cependant, il y a une chose que je ne peux pas résoudre moi-même et c'est un sujet très précis de ma question.

Comment puis-je intégrer GLSL dans ma langue? Dans le compilateur C#, je suis allé ligne par ligne et vérifié si la ligne commence avec des caractères spéciaux (comme% ou [) et plus tard fait de nombreuses astuces & hacks en utilisant string_replace et/ou regexes.

Maintenant je voudrais écrire une grammaire de Bison propre et le faire correctement. Mais y compris toute la syntaxe de GLSL me fait peur. C'est un langage assez gros et compliqué, en constante évolution. Et le plus que je ferais serait de passer à travers tout ce code GLSL de toute façon.

Si vous n'avez aucune expérience de la programmation graphique GLSL/Cg/graph, ce n'est pas très important. La question peut être réécrite dans la «ligne du bas». Donc, si vous souhaitez en ajouter une très petite en C++ avec Flex/Bison, comment le feriez-vous? Par exemple, possibilité de déclarer les fonctions void xxx() avec la syntaxe: foo%%: xxx?

+2

Adobe détournant ce drapeau «flexible» vraiment nul. (Mais utiliser 'yacc' et' lex' pourrait être meilleur quand même.) – sbi

+0

bon point, changé – programmer

+1

Il y a une balise 'gnu-flex', BTW. –

Répondre

1

J'ai ajouté des mécanismes de multithreading à pascal pour un projet d'école une fois, donc j'ai dû faire face à cela.Ce que j'ai fait, c'est que j'ai trouvé une définition BNF de pascal et que j'ai copié cela, en faisant principalement mes jetons égaux au texte dans 99% des cas, et en ajoutant le nouveau code de langue intermédiaire dans le 1% de nouveaux jetons. Pascal est simple, donc la définition de BNF est relativement simple. C++, pas tellement. Le langage de programmation C++ de Stroustroup possède une grammaire de langage pratiquement prête pour l'analyse, mais beaucoup de code à copier à la main. Peut-être qu'un certain website peut vous aider à trouver un ensemble bison/lex pour C++ "standard", et vous pouvez le modifier.

EDIT: J'ai trouvé mes fichiers yacc, alors voici un petit exemple de mon code pascals

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*/ 
} 

les deux premiers éléments étaient juste norme pascals: Je copiais l'entrée des jetons dans les chaînes de sortie in extenso (c.-à- Je n'ai pas réellement modifié quelque chose du fichier d'entrée).

le troisième élément (mon mot clé THREAD) n'était, évidemment, pas standard pascal. J'ai donc transformé la sortie en quelque chose que je pourrais réellement compiler en pascal standard.

Fondamentalement, pour compiler mon pascal "threadé", j'ai dû prendre mon fichier source, le passer à travers mon analyseur, puis compiler la sortie.

Questions connexes