2010-05-27 13 views
2

J'ai besoin d'aide pour la construction d'une grammaire de bisons.Comment écrire un grammaire de bisons pour WDI?

De mon autre question: Je suis en train de faire une méta-langage pour écrire le code de balisage (comme xml et html) Wich peuvent être directement intégrés dans le code C/C++. Voici un exemple simple écrit dans cette langue, je l'appelle WDI (Interface de développement Web):

/* 
    * Simple wdi/html sample source code 
    */ 
#include <mySite> 

string name = "myName"; 
string toCapital(string str); 

html 
{ 
    head { 
    title { mySiteTitle; } 
    link(rel="stylesheet", href="style.css"); 
    } 
    body(id="default") { 
    // Page content wrapper 
    div(id="wrapper", class="some_class") { 
    h1 { "Hello, " + toCapital(name) + "!"; } 

    // Lists post 
    ul(id="post_list") { 
    for(post in posts) { 
     li { a(href=post.getID()) { post.tilte; } } 
    } 
    } 
    } 
    } 
} 

Fondamentalement, il est une source de C avec une interface conviviale pour html. Comme vous pouvez le voir, le style traditionnel basé sur les balises est remplacé par C-like, avec des blocs délimités par des accolades. J'ai besoin de construire un interpréteur pour traduire ce code en html et l'insérer postérieurement en C, afin qu'il puisse être compilé. La partie C reste intacte. A l'intérieur de la source wdi, il n'est pas nécessaire d'utiliser des impressions, chaque déclaration de retour sera utilisée pour la sortie (dans la fonction printf). La sortie du programme sera un code html propre.

Ainsi, par exemple une rubrique 1 tag serait transformé comme ceci:

h1 { "Hello, " + toCapital(name) + "!"; } 
// would become: 
printf("<h1>Hello, %s!</h1>", toCapital(name)); 

Mon objectif principal est de créer un interprète pour traduire la source WDI html comme ceci:

tag(attributes) {content} =><tag attributes>content</tag>

Deuxièmement, le code html renvoyé par l'interpréteur doit être inséré dans le code C avec printfs. Les variables et les fonctions qui se produisent à l'intérieur de wdi doivent également être triées afin de pouvoir les utiliser comme paramètres printf (le cas de toCapital (nom) dans la source d'échantillon).

Voici mes flex/fichiers bison:

id  [a-zA-Z_]([a-zA-Z0-9_])* 
number [0-9]+ 
string \".*\" 

%% 

{id} { 
     yylval.string = strdup(yytext); 
     return(ID); 
    } 

{number} { 
     yylval.number = atoi(yytext); 
     return(NUMBER); 
    } 

{string} { 
     yylval.string = strdup(yytext); 
     return(STRING); 
    } 

"(" { return(LPAREN); } 
")" { return(RPAREN); } 
"{" { return(LBRACE); } 
"}" { return(RBRACE); } 
"=" { return(ASSIGN); } 
"," { return(COMMA); } 
";" { return(SEMICOLON); } 

\n|\r|\f { /* ignore EOL */ } 
[ \t]+ { /* ignore whitespace */ } 
.  { /* return(CCODE); Find C source */ } 

%% 

%start wdi 
%token LPAREN RPAREN LBRACE RBRACE ASSIGN COMMA SEMICOLON CCODE QUOTE 

%union 
{ 
    int number; 
    char *string; 
} 

%token <string> ID STRING 
%token <number> NUMBER 

%% 
wdi 
    : /* empty */ 
    | blocks 
    ; 

blocks 
    : block 
    | blocks block 
    ; 

block 
    : head SEMICOLON 
    | head body 
    ; 

head 
    : ID 
    | ID 
    attributes 
    ; 

attributes 
    : LPAREN RPAREN 
    | LPAREN attribute_list RPAREN 
    ; 

attribute_list 
    : attribute 
    | attribute COMMA attribute_list 
    ; 

attribute 
    : key ASSIGN value 
    ; 

key 
    : ID {$$=$1} 
    ; 

value 
    : STRING {$$=$1} 
    /*| NUMBER*/ 
    /*| CCODE*/ 
    ; 

body 
    : LBRACE content RBRACE 
    ; 

content 
    : /* */ 
    | blocks 
    | STRING SEMICOLON 
    | NUMBER SEMICOLON 
    | CCODE 
    ; 

%% 

J'ai des difficultés sur la définition d'une grammaire pour la langue, en particulier dans WDI de fractionnement et le code C. Je viens juste d'apprendre les techniques de traitement de la langue, donc j'ai besoin d'orientation. Est-ce que quelqu'un pourrait corriger mon code ou donner quelques exemples de ce qui est la bonne façon de résoudre ce problème?

+2

vous demandez des corrections pour votre code - pouvez-vous nous dire ce qui ne va pas? Refuse-t-il de compiler, de lancer une erreur d'exécution, ou d'accepter/rejeter les mauvaises choses? Des éclaircissements nous aideraient à vous aider. –

+0

Cela fonctionne! Je veux dire que la grammaire accepte la source WDI. Mais je pense que ce code est incomplet. Je ne sais pas comment gérer les variables de jetons et les utiliser plus tard, par exemple ... – Rizo

+2

Si c'est le cas, vous voudrez faire quelques recherches pour implémenter une table de symboles. C'est la structure de données dont vous aurez besoin pour stocker les jetons (avec tous les attributs hérités ou synthétisés pour eux) pour une utilisation ultérieure. –

Répondre

2

Si votre intention est de parse code C et code WDI intégré, vous êtes dans un tour difficile. Les générateurs d'analyseurs LALR (1) (y compris Bison) sont notoirement mauvais lors de l'analyse de C, sans parler des choses plus compliquées que C (C + WDI).

Soit vous devrez:

a) apprendre à faire Bison Parse C par emmêlement analyse syntaxique et la construction de la table des symboles (sens, aller lutte avec GNU GCC pour voir comment ils l'ont fait),

b) Passer à un générateur d'analyseur syntaxique plus fort tel qu'un générateur d'analyseur GLR (qui Bison a une option pour) et d'apprendre comment faire face à des grammaires ambiguës et comment les résoudre,

ou

c) la conception WDI comme une sorte de grammaire de l'île , dans lequel le but est de choisir le code WDI et de laisser tout ce qui n'est pas WDI comme des chaînes opaques (dans votre cas, destiné à être sorti en tant que code C présumé).Cette dernière approche est beaucoup plus facile, et c'est à peu près ce que font tous les langages de pages Web (ASP, PHP, JSP ...). L'avantage est que cela est beaucoup plus facile, et il suffit d'écrire la grammaire pour WDI lui-même et un lexer qui va ramasser tout ce qui n'est pas WDI comme une chaîne de caractères. L'inconvénient est que vous ne serez pas en mesure de faire interagir correctement WDI et C/et/ou de vérifier la validité d'un programme WDI avec votre analyseur. Voir cette question SO pour un peu plus fond:

Island grammar antlr3

Ce serait plus facile si vous allez en apprendre davantage sur la technologie de compilateur plus en détail avant de commencer ce projet.