我们被要求使用FLEX软件并用C语言编写代码。第一个字符串是从一个文本文件中收集的,这是我在LEX中是如何做到的:
%option noyywrap yylineno
%{
#define YYSTYPE char *
#include "y.tab.h"
%}
%%
[ \t\n]+ {}
"NAZIV" {return _NAZIV;}
"GODINA" {return _GODINA;}
"TIP" {return _TIP;}
"ECTS" {return _ECTS;}
":" {return _DVOTACKA;}
";" {return _SEMICOLON;}
[A-Za-z]+ {yylval=strdup(yytext); return _VRIJEDNOST;}
[0-9]+ {yylval =atoi(yytext); return _BROJ_BODOVA;}
所以我需要在倒数第二行中收集一个字符串[A-Za-z]+
。现在在Yacc中,如果文本文件在该点显示“obavezni”,我需要增加一个计数器。当在文本文件中遇到该点时,我这样做:
: _TIP _DVOTACKA _VRIJEDNOST _SEMICOLON
{result=strcmp($3,string);if(result==0) prvi_uslov=1; }
;
上面的字符串是char string[]="obavezni";
这样我就得到了一堆警告,关于不能比较const * char
和*char
,其中一个参数是YYSTYPE
类型的。
我昨天开始做Yacc/野牛,我不知道这意味着什么,我只需要一个简单的方法来比较从文本文件中收集的值和现有的字符串,如果它们是相同的,计数器就会上升,仅此而已。
2条答案
按热度按时间6jygbczu1#
我一直在纠结这个例子,但我找到了一个解决方案,输入以下命令后错误消失了:
我的代码在这里也有一点不同:
6psbrbz92#
由Yacc(或者您实际使用的Yacc衍生物,可能是野牛)生成的解析器和由Flex生成的词法分析器是独立的程序;这两个工具彼此不知道。两个程序之间的通信(至少在默认情况下)是通过全局变量
yylval
进行的。默认情况下,yylval
的类型为int
,但这种情况很少出现。在大多数实际解析应用程序中,有必要给予yylval
一个不同的类型,而且语法分析器和词法分析器必须就这个类型达成一致,这个类型被称为语法分析器的“语义类型”;它用于产生式规则中所有语法符号的语义值。改变
yylval
语义类型的传统方法是(重新)定义预处理器宏YYSTYPE
。如果你这样做,你必须确保新的定义包含在解析器和词法分析器中,这意味着要么将它包含在.l
和.y
文件的序言中。你似乎只在词法分析器文件中做了这件事。结果是在解析器中,语义类型是默认的int
,C编译器抱怨使用$3
作为strcmp
的参数,因为$3
是int
,这不是字符串比较的有效参数类型。但是我建议你不要把预处理器定义也添加到你的解析器中,尽管现在这样做是可行的,相反,你应该使用野牛声明来声明语义类型:
如果你这样做,野牛会把声明放到头文件中,你已经把它
#include
到词法分析器中了,这样,单一的声明将保证类型在词法分析器和语法分析器中是相同的。