lex yacc中的语法错误

时间:2014-11-02 13:43:52

标签: yacc lex

这是我的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的经验相对较少

1 个答案:

答案 0 :(得分:1)

  1. 该语法只会成功解析最后有XMLEND的文件。但是,所有文本文件都以换行符结尾。

  2. 虽然您可以通过在开始规则的末尾添加换行符来解决这个问题,但尝试解析空格几乎总是一个坏主意。一般来说,除了面向行的语言 - xml不是 - 最好忽略空格。

  3. 您对strcat的使用不正确。从GNU / Linux系统引用man strcat

      

    strcat()函数将src字符串附加到dest字符串,覆盖dest末尾的终止空字节('\ 0'),然后添加一个终止空字节。字符串可能不重叠, dest字符串必须有足够的空间用于结果。如果dest不够大,程序行为是不可预测的;缓冲区溢出是攻击安全程序的最佳途径。

    如果您的标准库中存在asprintf,则可能需要使用free()

  4. 此外,您永远不会strdup strdup生成的字符串,所以它们都会泄漏内存。一般来说,最好不要设置其字符串表示已知的asprintf标记 - 特别是单字符标记 - 但重要的是跟踪其字符串值已被新分配的标记。如果采用上述建议,这将适用于{{1}}生成的语义值。