【问题标题】:Syntax error in lex yacclex yacc 中的语法错误
【发布时间】:2014-11-02 13:43:51
【问题描述】:

这是我的 lex yacc 代码,用于解析 XML 文件并打印和标记之间的内容。

莱克斯

%{

%}
%%
"<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 的经验相对较少

【问题讨论】:

  • 查看我的语法。您必须指的是 hello 的结束标记。但我的语法将结束标签视为

标签: yacc lex


【解决方案1】:
  1. 该语法只会成功解析末尾有XMLEND 的文件。但是,所有文本文件都以换行符结尾。

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

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

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

    如果您的标准库中存在asprintf,您可能想使用它。

  4. 另外,你永远不会free()strdup产生的字符串,所以它们都会泄漏内存。一般来说,最好不要设置字符串表示已知的strdup 标记——尤其是单字符标记——但重要的是要跟踪其字符串值已被新分配的标记。如果采用上述建议,这将适用于使用asprintf 生成的语义值。

【讨论】:

  • 将 strcat 替换为 sprintf,并删除了单个字符串的 strdup。暂时将新生产线添加到开始生产中。瞧!有效。现在需要改进它
猜你喜欢
  • 2023-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多