这是我的lex yacc代码,用于解析XML文件并在标签之间打印内容。
LEX
%{
%}
%%
"<XML>" {return XMLSTART;}
"</XML>" {return XMLEND;}
[a-z]+ {yylval=strdup(yytext); return TEXT;}
"<" {yylval=strdup(yytext);return yytext[0];}
">" {yylval=strdup(yytext);return yytext[0];}
"\n" {yylval=strdup(yytext);return yytext[0];}
. {}
%%
YACC
%{
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define YYSTYPE char *
%}
%token XMLSTART
%token XMLEND
%token TEXT
%%
program : XMLSTART '\n' A '\n' XMLEND {printf("%s",$3);
}
A : '<' TEXT '>' '\n' A '\n' '<' TEXT '>' { $$ = strcat($1,strcat($2,strcat($3,strcat($4,strcat($5,strcat($6,strcat($7,strcat($8,$9))))))));}
| TEXT
%%
#include"lex.yy.c"
我收到语法错误,尝试在某些地方使用ECHO但未找到错误。 我正在使用的输入文件是:
<XML>
<hello>
hi
<hello>
</XML>
请帮我弄清楚错误。我使用lex和yacc的经验相对较少
答案 0 :(得分:1)
该语法只会成功解析最后有XMLEND
的文件。但是,所有文本文件都以换行符结尾。
虽然您可以通过在开始规则的末尾添加换行符来解决这个问题,但尝试解析空格几乎总是一个坏主意。一般来说,除了面向行的语言 - xml不是 - 最好忽略空格。
您对strcat
的使用不正确。从GNU / Linux系统引用man strcat
:
strcat()
函数将src字符串附加到dest字符串,覆盖dest末尾的终止空字节('\ 0'),然后添加一个终止空字节。字符串可能不重叠, dest字符串必须有足够的空间用于结果。如果dest不够大,程序行为是不可预测的;缓冲区溢出是攻击安全程序的最佳途径。
如果您的标准库中存在asprintf
,则可能需要使用free()
。
此外,您永远不会strdup
strdup
生成的字符串,所以它们都会泄漏内存。一般来说,最好不要设置其字符串表示已知的asprintf
标记 - 特别是单字符标记 - 但重要的是跟踪其字符串值已被新分配的标记。如果采用上述建议,这将适用于{{1}}生成的语义值。