将数据从flex传递到野牛语法

问题描述 投票:0回答:2

我的弹性/野牛语法有问题。不知道这是否是我建立递归的方式。

[当尝试访问通过yylval传递的数据时,我将对生产的每个元素使用$ 1 ...变量。但是,这样做时并不会将值拆分为每个令牌。它打印整个作品。这仅发生在元数据生成中的第二个句子中,第一个似乎可以。

我打算创建一个包含check(int token_val)switch(token_val)函数,并检查每个标记的返回值,然后适当地对其yytext进行操作。有没有一种方法可以使用$变量符号,该符号将为我提供命令产生的返回值?还是这是做事的不正确方法?

我已经检查了相关参考,但也许我错过了一些,希望有人澄清。

代码:野牛



input: input metadata
     | metadata
     ;

metadata: command op data {printf("%s is valid.\n", $3);} // check_data($1) ?
        | data op data op data op data {printf("row data is valid\n\t %s\n", $1);}
        ;

command: PROD_TITL
      |  _DIR
      |  DOP
      |  DIT
      |  FORMAT
      |  CAMERA
      |  CODEC
      |  DATE
      |  REEL
      |  SCENE
      |  SLATE
      ;

op: EQUALS
  | COLON
  | SEP
  ;

data: META
    | REEL_ID
    | SCENE_ID
    | SLATE_ID
    | TAKE
    | MULTI_T
    | LENS
    | STOP
    | FILTERS
    ;

%%

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


lex:

%{
#include <stdio.h>
#include <string.h>
#include "ca_mu.tab.h"
%}

%option yylineno

%%


\"[^"\n]*["\n]              {yylval = yytext; return META;}
[aA-aZ][0-9]+               {yylval = yytext; return REEL_ID;}
([0-9aA-zZ]*\/[0-9aA-zZ]*)  {yylval = yytext; return SCENE_ID;}
[0-9]+                      {yylval = yytext; return SLATE_ID;}
[0-9][aA-zZ]+               {yylval = yytext; return TAKE;}
[0-9]+-[0-9]+               {yylval = yytext; return MULTI_T;}
[0-9]+MM                    {yylval = yytext; return LENS;}
T[0-9]\.[0-9]+              {yylval = yytext; return STOP;}
"{"([^}]*)"}"               {yylval = yytext; return FILTERS;}

输出样本:

"My Production" is valid.
"Dir Name" is valid.
"DOP Name" is valid.
"DIT Name" is valid.
"16:9" is valid.
"Arri Alexa" is valid.
"ProRes" is valid.
"02/12/2020" is valid.
A001 is valid.
23/22a is valid.
001 is valid.
row data is valid
         1, 50MM, T1.8, { ND.3 }  // $1 prints all tokens?
row data is valid
         3AFS,   50MM, T1.8, {ND.3}

输入

/* This is a comment */

production_title = "My Production"
director         = "Dir Name"
DOP              = "DOP Name"
DIT              = "DIT Name"
format           = "16:9"
camera           = "Arri Alexa"
codec            = "ProRes"
date             = "02/12/2020"

reel: A001
  scene: 23/22a
    slate: 001
      1, 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}

END

c bison yacc lex
2个回答
2
投票

问题出在这里,在您的扫描仪操作中:

yylval = yytext;

您绝对不能这样做。

yytext指向一个临时缓冲区,该缓冲区仅在下一次调用yylex()之前有效,这意味着您正在有效地使yylval成为悬空指针。始终复制字符串,如:

yylval = strdup(yytext);

((当您不再需要副本时,请不要忘记在复制的字符串上调用free()。]


1
投票

我认为您的语言太简单,没有定义输入的结构。例如:

reel: A001                     // repetition of reels, consisting of....
  scene: 23/22a                // repetition of scenes, consisting of...
    slate: 001                 // repetition of slates, consisting of...
      1, 50MM, T1.8, { ND.3 }  // repetition of slate data

这是一个结构,所以输入是:

movie: metadata reels
     ;

metadata: /* see your stuff */ ;

reels: reel
     | reels reel
     ;

reel: REEL REEL_ID scenes
    ;

scenes: scene
     | scenes scene
     ;

scene: SCENE SCENE_ID slates
     ;

slates: slate
      | slates slate
      ;

slate: SLATE SLATE_ID slate_datas
     ;

slate_datas: slate_data
    | slate_datas slate_data
    ;

slate_data: /*your stuff*/ ;
© www.soinside.com 2019 - 2024. All rights reserved.