yacc定义的结构

yacc定义的结构,c,yacc,lex,C,Yacc,Lex,我正在为个人项目的标记语言编写解析器: 样本: /* This is a comment */ production_title = "My Production" director = "Joe Smith" DOP = "John Blogs" DIT = "Random Name" format = "16:9" camera = "Arri Alexa" codec

我正在为个人项目的标记语言编写解析器:

样本:

/* This is a comment */

production_title = "My Production"
director         = "Joe Smith"
DOP              = "John Blogs"
DIT              = "Random Name"
format           = "16:9"
camera           = "Arri Alexa"
codec            = "ProRes"
date             = _auto

Reel: A001
  Scene: 23/22a
    Slate: 001
      1-2, 50MM, T1.8, {ND.3}
      3AFS,   50MM, T1.8, {ND.3}
    Slate: 002:
      1,  65MM, T1.8, {ND.3 BPM1/2}
    Slate: 003:
      1-3, 24MM, T1.9 {ND.3}

Reel: A002
  Scene: 23/22a
    Slate: 004
      1-5, 32MM, T1.9, {ND.3}
  Scene: 23/21
    Slate: 005
      1, 100MM, T1.9, {ND.6}

END
我已经开始学习lex和yacc,并且遇到了一些关于语法定义结构的问题

yacc.y

%{
#include <stdio.h>
int yylex();
void yyerror(char *s);
%}

%token PROD_TITL _DIR DOP DIT FORMAT CAMERA CODEC DATE EQUALS
%right META

%%

meta: PROD_TITL EQUALS META {
            printf("%s is set to %s\n",$1, $3);
      }
      | _DIR EQUALS META {
            printf("%s is set to %s\n",$1, $3);
      }
%%

int main(void) {
  return yyparse();
}

void yyerror(char *s) {fprintf(stderr, "%s\n", s);}

这是问题的根源还是其他问题?

这是两个不同的问题

  • 你的语法如下,不包括动作:

    meta: PROD_TITL EQUALS META
        | _DIR EQUALS META 
    
    这意味着您的语法接受两个序列中的一个,两个序列正好有三个标记。也就是说,它接受“PROD_TITL等于META”或“_DIR等于META”。就这样。一旦它找到了这些东西中的一个,它就已经尽可能多地解析了它知道如何解析的内容,并且它希望被告知输入已经完成。任何其他输入都是错误的

  • 编译器正在抱怨
    yylval=strdup(yytext)yylval
    属于
    int
    类型。这是yacc/bison的默认语义类型;如果您不做任何更改,bison将假定这一点,它将插入
    extern int yylval,以便lexer知道语义类型是什么。如果你在互联网上搜索,你可能会发现各种各样的宏黑客建议改变这一点,但使用“现代”野牛的正确方法是在序言中的某个地方,在野牛文件中插入以下声明:

    %declare api.value.type { char* }
    
    稍后,您可能会发现您希望使用联合类型,而不是将所有内容都设置为字符串。在你达到这一点之前,你应该阅读野牛手册中关于野牛的章节。(事实上,建议您从头到尾阅读《野牛手册》,包括第2节中的简单示例。它没有那么长,而且非常容易阅读。)


  • 干杯,我刚找到一本关于莱克斯和亚克的奥莱利的书,很有帮助。我在我的问题上做得更进一步了,所以我会结束这个now@hdcdigi当前位置OReilly的书不错,但Lex&Yacc版有点过时。一定要试试野牛手册。这真的是一个很好的介绍。如果你有什么不明白的地方,我们可以试着改进。(我们这里是更广泛的野牛用户社区。我不是野牛队的成员或任何人。)谢谢,我一定会看的。我想我现在正在慢慢地想事情。我已经将代码添加到github中,我将很快花一些时间创建自述文件并添加项目详细信息
    ca_mu.l: In function ‘yylex’:
    ca_mu.l:9:9: warning: assignment makes integer from pointer without a cast [-Wint-conversion]
     "production_title"  {yylval = strdup(yytext); return PROD_TITL;}
             ^
    ca_mu.l:10:9: warning: assignment makes integer from pointer without a cast [-Wint-conversion]
     "director"          {yylval = strdup(yytext); return _DIR;}
             ^
    ca_mu.l:20:10: warning: assignment makes integer from pointer without a cast [-Wint-conversion]
     \"[^"\n]*["\n]      { yylval = strdup(yytext);
              ^
    
    meta: PROD_TITL EQUALS META
        | _DIR EQUALS META 
    
    %declare api.value.type { char* }