gpt4 book ai didi

flex-lexer - 如何在 flex 中使用 yylval

转载 作者:行者123 更新时间:2023-12-01 00:32:51 26 4
gpt4 key购买 nike

我正在尝试在 Windows 上使用 FLEX 构建一个词法分析器。
我总是收到一个错误:

"undefined reference to `yylval'"



我将 yylval 声明为 extern键入所有定义如下:
  %option noyywrap
%{
#include<stdio.h>
#include<stdlib.h>
#include "tokens.h"
int nline = 1;
int size_token_array = 100;
int number_of_tokens_in_array = 0;
int inc_token_array = 50;
token *token_store ;
extern yylval;

%}
delim [ \t]
delim_nl [\n]
ws {delim}+
nl {delim_nl}+
letter [a-z]
digit [0-9]
id {letter}(letter.digit)*
int_num (0|([+-]?([1-9]{digit}*)))
real_num [+-]?{digit}+(\.{digit}+)
rel_op ">"|"<"|"<="|">="|"=="|"!="
binary_ar_op "+"|"-"|"*"|"/"|"="
task_id {letter}(letter+digit)*
signal_id {letter}(letter+digit)*

%%
"parbegin" {create_and_store_token(TOKEN_PARBEGIN,yytext,nline); return 1;}
"parend" {create_and_store_token(TOKEN_PAREND,yytext,nline); return 1;}
"task" {create_and_store_token(TOKEN_TASK,yytext,nline); return 1;}
"{" {create_and_store_token('{',yytext,nline); return 1;}
"}" {create_and_store_token('}',yytext,nline); return 1;}
"begin" {create_and_store_token(TOKEN_BEGIN,yytext,nline); return 1;}
"end" {create_and_store_token(TOKEN_END,yytext,nline); return 1;}
"integer" {create_and_store_token(TOKEN_INTEGER,yytext,nline); return 1;}
"real" {create_and_store_token(TOKEN_REAL,yytext,nline); return 1;}
"||" {create_and_store_token(TOKEN_PARALLEL,yytext,nline); return 1;}
";" {create_and_store_token(';',yytext,nline); return 1;}
"," {create_and_store_token(',',yytext,nline); return 1;}
"do" {create_and_store_token(TOKEN_DO,yytext,nline); return 1;}
"until" {create_and_store_token(TOKEN_UNTIL,yytext,nline); return 1;}
"od" {create_and_store_token(TOKEN_OD,yytext,nline); return 1;}
"send" {create_and_store_token(TOKEN_SEND,yytext,nline); return 1;}
"accept" {create_and_store_token(TOKEN_ACCEPT,yytext,nline); return 1;}
"(" {create_and_store_token('(',yytext,nline); return 1;}
")" {create_and_store_token(')',yytext,nline); return 1;}
"<" {create_and_store_token(LT,yytext,nline); yylval=rel_op; return 1;}
">" {create_and_store_token(GT,yytext,nline); yylval=rel_op; return 1;}
"<=" {create_and_store_token(LE,yytext,nline); yylval=rel_op; return 1;}
">=" {create_and_store_token(GE,yytext,nline); yylval=rel_op; return 1;}
"==" {create_and_store_token(EQ,yytext,nline); yylval=rel_op; return 1;}
"!=" {create_and_store_token(NE,yytext,nline); yylval=rel_op; return 1;}
"*" {create_and_store_token('*',yytext,nline); yylval=binary_ar_op; return 1;}
"/" {create_and_store_token('/',yytext,nline); yylval=binary_ar_op; return 1;}
"+" {create_and_store_token('+',yytext,nline); yylval=binary_ar_op; return 1;}
"-" {create_and_store_token('-',yytext,nline); yylval=binary_ar_op; return 1;}
"=" {create_and_store_token('=',yytext,nline); yylval=binary_ar_op; return 1;}
{ws} ;
{nl} nline++;
id {create_and_store_token(TOKEN_ID,yytext,nline); return 1;}
int_num {create_and_store_token(TOKEN_INT_NUM,yytext,nline); return 1;}
real_num {create_and_store_token(TOKEN_REAL_NUM,yytext,nline); return 1;}
binary_ar_op {create_and_store_token(TOKEN_AR_OP,yytext,nline); return 1;}
"task_id" {create_and_store_token(TOKEN_TASK_ID,yytext,nline); return 1;}
"signal_id" {create_and_store_token(TOKEN_SIGNAL_ID,yytext,nline); return 1;}

%%
int main()
{
token_store = (token*)calloc(size_token_array,sizeof(token));
free(token_store);
return 0;

}

void create_and_store_token(int token_type,char* token_lexeme,int line_number){

token new_token;
new_token.ivalue = token_type;
new_token.lexema = token_lexeme;
new_token.line_number = line_number;

if(size_token_array == (number_of_tokens_in_array-10)){

token_store = (token*)realloc(token_store,inc_token_array*sizeof(token));
size_token_array+=inc_token_array;
number_of_tokens_in_array++;
token_store[number_of_tokens_in_array]= new_token;

}
else{
token_store[number_of_tokens_in_array]= new_token;
number_of_tokens_in_array++;

}
}

int nextToken(){
return yylex();
}

void backToken(){
token_store[number_of_tokens_in_array].ivalue = 0;
token_store[number_of_tokens_in_array].lexema = "";
token_store[number_of_tokens_in_array].line_number = 0;
number_of_tokens_in_array--;
}

有人知道我应该如何解决这个问题吗?

最佳答案

extern yylval;意味着 yylval在其他地方定义。所以你必须这样做。

通常它是在yacc/bison 生成的解析器中定义的,因此在链接扫描器和解析器时可以解析名称。如果您不使用 bison/yacc,则必须定义 yylval你自己。 (如果你真的需要它。你的代码没有给出你需要什么的太多提示。)

顺便说一句,您的代码还有许多其他问题。一个特别明显的就是不能使用指针yytext的值。在扫描仪移动到下一个 token 之后。如果您需要 yytext 指向的字符串的持久副本,您需要制作自己的副本(并在不再需要时释放为副本分配的内存。)

您的许多正则表达式也是不正确的。宏使用(“定义”)必须用大括号括起来,所以

id {create_and_store_token(TOKEN_ID,yytext,nline); return 1;} 

不会符合你的期望;它只会匹配两个字符的序列 id。将其更改为 {id}是一个开始,
但是 id的定义也不正确。

就我个人而言,我避免使用宏,因为它们不会给代码增加任何值(value),IMO;他们经常造成困惑。例如,您对 letter 的定义只包含小写字母,对于阅读您的代码的人来说根本不明显。最好使用 Posix 字符类,它不需要定义并且其含义是明确的: [[: alpha:]]对于字母, [[:lower:]]对于小写字母, [[:alnum:]]用于字母或数字等。

关于flex-lexer - 如何在 flex 中使用 yylval,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43396132/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com