我的弹性/野牛语法有问题。不知道这是否是我建立递归的方式。
[当尝试访问通过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
问题出在这里,在您的扫描仪操作中:
yylval = yytext;
您绝对不能这样做。
yytext
指向一个临时缓冲区,该缓冲区仅在下一次调用yylex()
之前有效,这意味着您正在有效地使yylval
成为悬空指针。始终复制字符串,如:
yylval = strdup(yytext);
((当您不再需要副本时,请不要忘记在复制的字符串上调用free()
。]
我认为您的语言太简单,没有定义输入的结构。例如:
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*/ ;