How would I declare a grammar rule for a number of tags in any order?

家住魔仙堡 提交于 2019-12-13 04:25:10

问题


I am trying to write a compiler for a formating language.This language has a start and an end property and a set of document and text properties. The first is just info for the document itself where as the second is the actual document (titles, paragraphs, lists... the usual). The first set must always follow the start property and must contain all properties BUT in any order the user might like.

Assuming that my tokens for the properites are PROP1, PROP2, PROP3 and PROP4 I can use recursion and an OR for all the properties so that the user can define any document property he wants.

doc_properties
    : /* empty */
    : doc_properties property  
    ;
property
    : PROP1
    : PROP2
    : PROP3
    : PROP4
    ;

BUT how do I make him to define them all and only once. One way that I thought (the easy and crude way I would like to avoid) is because I only have 4 document properties I can just make an or of all possible combinations. I am pretty sure there is another way. Any help?

My grammar so far is pretty simple and small

%{ /* C Stuff */ %}

/* union and error stuff and tokens */

%%

source
    : /* empty */  
    | entry_point doc_properties txt_properties exit_point
    ;

entry_point
    : SLASH BLOCK_S LBRACE DOC RBRACE 
    ;

doc_properties 
    : /* This is where my question goes */  
    ;

txt_properties
    : /* empty */  
    ;

exit_point
    : SLASH BLOCK_E LBRACE DOC RBRACE
    ;


%%

int main (int argc, char* argv[])
{
    /* various checks for the arguments and the input output files */

        yyin = fopen(argv[1], "r");
        yyout = fopen(fn, "w");     
        //do{
            yyparse();
        //}while(!feof(yyin));
        fclose(yyin);
        fclose(yyout);

    return 0;
}

void yyerror(const char* str) {
    fprintf(stderr,"syntax error[%d]: %s\n",yylineno, str);
}

Also on an unrelated note does using yyparse() inside a do-while loop or just once by itself has any difference? Because I see it both ways and while the do-while loop makes more sense to me (because it requests a token parses and then again) I am not sure if the function repeats itself or something...


回答1:


There is a number of syntax rules that are best enforced by semantic checks rather than by the grammar itself. For instance, in C like languages, the break construct can only appear inside loops (and switch), yet it is far simpler to accept it like any regular statement, and later, in the semantic analysis pass, reject invalid uses to break.

You could use a similar pattern: accept any combination of PROP, and later reject those that do not respect your constraints. Of course, you can also do this while parsing, using YYERROR to raise an error when appropriate.

Wrt to your second question, yyparse is to be called only once, but then of course it is in charge of calling the scanner (yylex) repeatedly. Note that Bison offers "push-parsers", where you are in charge of calling yylex repeatedly, and pass its results to yyparse (repeatedly too). See http://www.gnu.org/software/bison/manual/bison.html#Push-Decl for more details.



来源:https://stackoverflow.com/questions/13786896/how-would-i-declare-a-grammar-rule-for-a-number-of-tags-in-any-order

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!