從構成 Bison 找到的規則的一個或多個標記中獲取結果字串的正確方法是什么?
timer:
TILDE amount {
printf("Timer: Amount:%s\n",$2 );
$$ = $2;
}
| TILDE WORD amount {
printf("Timer: %s Amount:%s\n",$2, $3 );
// make timer string
$$ = malloc(strlen($2) strlen($3) 10);
sprintf($$, "%s %s", $2, $3);
free($2);
free($3);
}
| TILDE MULTIWORD amount {
printf("Timer: %s Amount:%s\n",$2, $3 );
// make timer string
$$ = malloc(strlen($2) strlen($3) 10);
sprintf($$, "%s %s", $2, $3);
free($2);
}
;
time、amount 和 WORD 都是字串型別,MULTIWORD 也是。
例如,如果第一條規則匹配,意味著有一個波浪號“~”和一個數量,通常是字串格式的“3”這樣的數字,獲得結果值的最佳方法是什么,即“計時器”只是金額的價值?
如果第二條規則匹配,我將如何將 WORD 和金額添加到一個字串中并將它們放入 $$ 值中。我在 Bison 檔案中找不到關于此的任何內容。
編輯:忘記提及問題。列印出來的字串不僅僅是我想要傳遞的。例如,金額定義為:
amount:
// an empty amount - for one word timers
LCURL RCURL {
$$ = malloc(5);
$$[0] = ' ';
$$[1] = '\0';
}
| LCURL NUMBER RCURL {
// get string for amount
$$ = malloc(100);
sprintf($$, "%.3lf", $2);
}
| LCURL NUMBER UNIT RCURL {
// get string for amount
// remove % from unit
$$ = malloc(100 strlen($3) 5);
sprintf($$, "%.3lf %s", $2, $3);
}
| LCURL WORD RCURL {
$$ = $2;
}
| LCURL WORD UNIT RCURL {
$$ = malloc(strlen($2) strlen($3) 5);
sprintf($$, "%s%s", $2, $3);
}
| LCURL MULTIWORD RCURL {
$$ = $2;
}
| LCURL MULTIWORD UNIT RCURL {
$$ = malloc(strlen($2) strlen($3) 5);
sprintf($$, "%s%s", $2, $3);
}
;
當我在字串中放入 $2 時,它還會在其后面包含 RCURL。這會導致大量隨機字串和錯誤決議。
完整的詞法分析器檔案:
%{
#include "Cooklang.tab.h"
#include <stdlib.h>
void showError();
%}
SYMB_CHAR "$"|"="|" "|"-"|"_"|"*"|"`"
PUNC_CHAR "!"|"?"|","|"."|"/"|"&"|"("|")"|":"
NEW_LINE "\n"
WHITE_SPACE " "|"\t"
ALPHA_CHAR [a-zA-Z]
COOKLANG_CHAR ">"|"|"|"~"|"@"|"#"|":"|"{"|"}"|"%"
ZERO "0"
NON_ZERO_DIGIT [0-9]
DIGIT ({ZERO}|{NON_ZERO_DIGIT}){WHITE_SPACE}*
INTEGER ({ZERO}|({NON_ZERO_DIGIT}{DIGIT}*)){WHITE_SPACE}*
DECIMAL {INTEGER}"."{INTEGER}{WHITE_SPACE}*
FRACTIONAL {INTEGER}{WHITE_SPACE}*"/"{WHITE_SPACE}*{INTEGER}{WHITE_SPACE}*
WORD ({ALPHA_CHAR}|{DIGIT}|{SYMB_CHAR}) {WHITE_SPACE}*
HWORD "#"{WORD}
ATWORD "@"{WORD}
MULTIWORD {WORD}{2,}
UNIT "%"{WHITE_SPACE}*({MULTIWORD}*|{PUNC_CHAR}*)?
%%
[ \t]
"{" {return LCURL;}
"}" {return RCURL;}
"~" {return TILDE;}
{ATWORD} { yytext ;
yylval.string = yytext;
return ATWORD;
}
{HWORD} { yytext ;
yylval.string = yytext;
return HWORD;
}
{UNIT} { yytext ;
yylval.string = yytext;
return UNIT;}
{DIGIT} { yylval.number = strtod(yytext, NULL); return NUMBER;}
{INTEGER} { yylval.number = strtod(yytext, NULL); return NUMBER;}
{DECIMAL} { yylval.number = strtod(yytext, NULL); return NUMBER;}
{FRACTIONAL} { char * tok = strtok(yytext, "/");
double first = strtod(tok, NULL);
tok = strtok(NULL, "/");
double second = strtod(tok, NULL);
double final = first/second;
yylval.number = final;
return NUMBER;}
{WORD} { yylval.string = yytext;
return WORD;
}
{MULTIWORD} { yylval.string = yytext;
return MULTIWORD;
}
{PUNC_CHAR} { yylval.character = yytext[0];
printf("char: |%c|", yytext[0]);
return PUNC_CHAR; }
{NEW_LINE} {return NL;}
%%
int main( int argc, char ** argv ){
argv;
--argc;
if( argc > 0 ){
yyin = fopen(argv[0], "r");
} else {
yyin = stdin;
}
yyparse();
yylex();
printf("\n");
return 0;
}
uj5u.com熱心網友回復:
此詞法分析器操作不正確:
yylval.string = yytext; /* NEVER do this */
yytext是指向詞法分析器擁有的臨時存盤緩沖區的指標。它的內容僅在下一次呼叫詞法分析器之前有效;之后,指標可能不再有效(如果緩沖區被重新分配)或者內容將發生變化。
所以你必須復制指向的字串,yytext如果你需要它比詞法分析器動作更持久(如果你想將字串傳遞給決議器,你當然需要這樣做)。
你可以使用yylval.string = strdup(yytext),如果您有strdup(或包括實作),或者你可以自己動態分配存盤; 如果您選擇后一種解決方案,請記住yyleng包含文本長度的內容,因此不需要strlen:
/* 1 for the null terminator */
yylval.string = malloc(yyleng 1);
/* should check for allocation failure */
memcpy(yylval.string, yytext, yyleng 1);
free()當您不再需要它時,不要忘記復制。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/367103.html
上一篇:嘗試將資料庫(firestore)中的字串值與文本欄位中輸入的字串進行比較。我正在使用vue框架
下一篇:Python:字串測驗未評估
