neu*_*cer 5 yacc bison lexical-analysis
我想传递令牌的实际字符串.如果我有一个名为ID的令牌,那么我希望我的yacc文件实际知道调用了什么ID.我必须使用yylval将字符串传递给flex文件中的yacc文件.我怎么做?
Jon*_*onN 17
通过yylval返回字符串或任何复杂类型的关键是yacc在y.tab.h文件中创建的YYSTYPE联合.YYSTYPE是一个联合,其中包含yacc源文件中定义的每种令牌类型的成员.例如,要返回与yacc源文件中的SYMBOL标记关联的字符串,请在yacc源文件中使用%union声明此YYSTYPE联合:
/*** Yacc's YYSTYPE Union ***/
/* The yacc parser maintains a stack (array) of token values while
it is parsing. This union defines all the possible values tokens
may have. Yacc creates a typedef of YYSTYPE for this union. All
token types (see %type declarations below) are taken from
the field names of this union. The global variable yylval which lex
uses to return token values is declared as a YYSTYPE union.
*/
%union {
long int4; /* Constant integer value */
float fp; /* Constant floating point value */
char *str; /* Ptr to constant string (strings are malloc'd) */
exprT expr; /* Expression - constant or address */
operatorT *operatorP; /* Pointer to run-time expression operator */
};
%type <str> SYMBOL
Run Code Online (Sandbox Code Playgroud)
然后在LEX源文件中有一个与SYMBOL令牌匹配的模式.与该规则关联的代码负责返回表示SYMBOL的实际字符串.您不能只是将指针传递给yytext缓冲区,因为它是一个静态缓冲区,可以为匹配的每个标记重用.要返回匹配的文本,必须使用_strdup()在堆上复制静态yytext缓冲区,并通过yyval.str传递指向此字符串的指针.然后,yacc规则匹配SYMBOL令牌的责任,即在完成堆释放时,释放堆分配的字符串.
[A-Za-z_][A-Za-z0-9_]* {{
int i;
/*
* condition letter followed by zero or more letters
* digits or underscores
* Convert matched text to uppercase
* Search keyword table
* if found
* return <keyword>
* endif
*
* set lexical value string to matched text
* return <SYMBOL>
*/
/*** KEYWORDS and SYMBOLS ***/
/* Here we match a keywords or SYMBOL as a letter
* followed by zero or more letters, digits or
* underscores.
*/
/* Convert the matched input text to uppercase */
_strupr(yytext); /* Convert to uppercase */
/* First we search the keyword table */
for (i = 0; i<NITEMS(keytable); i++) {
if (strcmp(keytable[i].name, yytext)==0)
return (keytable[i].token);
}
/* Return a SYMBOL since we did not match a keyword */
yylval.str=_strdup(yytext);
return (SYMBOL);
}}
Run Code Online (Sandbox Code Playgroud)
小智 7
15与Yacc接口
flex的主要用途之一是作为yacc解析器生成器的伴侣.yacc解析器期望调用名为yylex()的例程来查找下一个输入标记.该例程应该返回下一个标记的类型,并将任何相关值放在全局yylval中.要将flex与yacc一起使用,可以指定yacc的`-d'选项,以指示它生成包含yacc输入中出现的所有%标记定义的文件y.tab.h.然后,此文件包含在flex扫描仪中.例如,如果其中一个令牌为TOK_NUMBER,则部分扫描程序可能如下所示:
Run Code Online (Sandbox Code Playgroud)%{ #include "y.tab.h" %} %% [0-9]+ yylval = atoi( yytext ); return TOK_NUMBER;
| 归档时间: |
|
| 查看次数: |
23334 次 |
| 最近记录: |