Flex/Bison Markdown 到 HTML 程序
Flex/Bison Markdown to HTML Program
这是家庭作业。我自己编辑的唯一代码是定义、规则和标记。到目前为止,我已经成功编译,但是当我尝试在降价文件 (.md) 上 运行 时出现分段错误,因此 HTML 输出只是一个空白文件。
%{
#define YYSTYPE char *
#include <string.h>
#include "miniMD2html.tab.h"
extern YYSTYPE yylval;
%}
%option yylineno
/* Flex definitions */
whitespace [ \t]+
newline [\n]+|{whitespace}[\n]+
textword [a-zA-Z:/.\-,\']+
integer [0-9]+
header #|##|###|####|#####
%%
{header} { return T_HEADER; }
{integer} { return T_INTEGER; }
{textword} { return T_TEXTWORD; }
{whitespace} { return T_BLANK; }
{newline} { return T_NEWLINE; }
%%
生成函数在另一个文件中给出。大部分只接受char*,generate_header函数接受一个int和char*,generate_image函数接受两个char*和两个int。语法可能看起来很奇怪,但这是作业中给出的内容。
%{
#include "global.h"
#include "stdlib.h"
#include "stdio.h"
#define YYSTYPE char *
extern int yylex();
int yywrap();
int yyerror(const char*);
int yyparse();
extern FILE *yyin;
Html_Doc *html_doc;
%}
/* Define tokens here */
%token T_BLANK T_NEWLINE
%token T_HEADER T_INTEGER T_TEXTWORD
%% /* Grammar rules and actions follow */
s: mddoc;
mddoc: /*empty*/ | mddoc paragraph;
paragraph: T_NEWLINE {add_linebreak(html_doc);}
| pcontent T_NEWLINE {add_element(html_doc, ); free();} ;
pcontent: header
| rftext {generate_paragraph();}
header: T_HEADER T_BLANK rftext {generate_header(strlen(), );}
rftext: rftext T_BLANK rftextword {strappend(, );}
| rftext rftextword {strappend(, );}
| rftextword
rftextword: textnum | image | format
image: "' {generate_image(, , atoi(), atoi());}
format: "**" text "**" {generate_bold();}
| '_' text '_' {generate_italic();}
| "**" format "**" {generate_bold();}
| '_' format '_' {generate_italic();}
text: text T_BLANK textnum {strappend(, );}
| text textnum {strappend(, );}
| textnum
textnum: T_TEXTWORD | T_INTEGER
%%
int main(int argc, char *argv[]) {
// yydebug = 1;
FILE *fconfig = fopen(argv[1], "r");
// make sure it is valid
if (!fconfig) {
printf("Error reading file!\n");
return -1;
}
html_doc = new_html_doc();
// set lex to read from file
yyin = fconfig;
int ret = yyparse();
output_result(html_doc);
del_html_doc(html_doc);
return ret;
}
int yywrap(){
return 1;
}
int yyerror(const char* s){
extern int yylineno;
extern char *yytext;
printf("error while parsing line %d: %s at '%s', ASCII code: %d\n", yylineno, s, yytext, (int)(*yytext));
return 1;
}
None 的 flex 规则曾经设置 yylval
的值,因此它将始终为 NULL。语法中对语义值 ($n
) 的所有引用也是如此。由于大多数采用 char*
的函数都假定它是一个有效的字符串,因此很可能其中一个函数很快就会尝试检查字符串值,而指针为 NULL 的事实肯定会导致段错误。
此外,您的语法中同时包含单个字符和带引号的字符串标记,none 可以由您的扫描器生成。因此,一旦在输入中遇到其中一个非单词字符,解析器很可能会因语法错误而停止。
在 bison 文件中,每个标记应由 ;
分隔
s: mddoc;
mddoc: /*empty*/ | mddoc paragraph;
paragraph: ...
注意
;
在 mmdoc 段落之后。
这是正确的,但以下标记没有很好地分开。
另外,正如@Rockcat所说,在flex文件中,你应该添加
yylval = strdup(yytext);
在将您的令牌返回到 bison 文件之前。
这是家庭作业。我自己编辑的唯一代码是定义、规则和标记。到目前为止,我已经成功编译,但是当我尝试在降价文件 (.md) 上 运行 时出现分段错误,因此 HTML 输出只是一个空白文件。
%{
#define YYSTYPE char *
#include <string.h>
#include "miniMD2html.tab.h"
extern YYSTYPE yylval;
%}
%option yylineno
/* Flex definitions */
whitespace [ \t]+
newline [\n]+|{whitespace}[\n]+
textword [a-zA-Z:/.\-,\']+
integer [0-9]+
header #|##|###|####|#####
%%
{header} { return T_HEADER; }
{integer} { return T_INTEGER; }
{textword} { return T_TEXTWORD; }
{whitespace} { return T_BLANK; }
{newline} { return T_NEWLINE; }
%%
生成函数在另一个文件中给出。大部分只接受char*,generate_header函数接受一个int和char*,generate_image函数接受两个char*和两个int。语法可能看起来很奇怪,但这是作业中给出的内容。
%{
#include "global.h"
#include "stdlib.h"
#include "stdio.h"
#define YYSTYPE char *
extern int yylex();
int yywrap();
int yyerror(const char*);
int yyparse();
extern FILE *yyin;
Html_Doc *html_doc;
%}
/* Define tokens here */
%token T_BLANK T_NEWLINE
%token T_HEADER T_INTEGER T_TEXTWORD
%% /* Grammar rules and actions follow */
s: mddoc;
mddoc: /*empty*/ | mddoc paragraph;
paragraph: T_NEWLINE {add_linebreak(html_doc);}
| pcontent T_NEWLINE {add_element(html_doc, ); free();} ;
pcontent: header
| rftext {generate_paragraph();}
header: T_HEADER T_BLANK rftext {generate_header(strlen(), );}
rftext: rftext T_BLANK rftextword {strappend(, );}
| rftext rftextword {strappend(, );}
| rftextword
rftextword: textnum | image | format
image: "' {generate_image(, , atoi(), atoi());}
format: "**" text "**" {generate_bold();}
| '_' text '_' {generate_italic();}
| "**" format "**" {generate_bold();}
| '_' format '_' {generate_italic();}
text: text T_BLANK textnum {strappend(, );}
| text textnum {strappend(, );}
| textnum
textnum: T_TEXTWORD | T_INTEGER
%%
int main(int argc, char *argv[]) {
// yydebug = 1;
FILE *fconfig = fopen(argv[1], "r");
// make sure it is valid
if (!fconfig) {
printf("Error reading file!\n");
return -1;
}
html_doc = new_html_doc();
// set lex to read from file
yyin = fconfig;
int ret = yyparse();
output_result(html_doc);
del_html_doc(html_doc);
return ret;
}
int yywrap(){
return 1;
}
int yyerror(const char* s){
extern int yylineno;
extern char *yytext;
printf("error while parsing line %d: %s at '%s', ASCII code: %d\n", yylineno, s, yytext, (int)(*yytext));
return 1;
}
None 的 flex 规则曾经设置 yylval
的值,因此它将始终为 NULL。语法中对语义值 ($n
) 的所有引用也是如此。由于大多数采用 char*
的函数都假定它是一个有效的字符串,因此很可能其中一个函数很快就会尝试检查字符串值,而指针为 NULL 的事实肯定会导致段错误。
此外,您的语法中同时包含单个字符和带引号的字符串标记,none 可以由您的扫描器生成。因此,一旦在输入中遇到其中一个非单词字符,解析器很可能会因语法错误而停止。
在 bison 文件中,每个标记应由 ;
s: mddoc;
mddoc: /*empty*/ | mddoc paragraph;
paragraph: ...
注意
;
在 mmdoc 段落之后。
这是正确的,但以下标记没有很好地分开。
另外,正如@Rockcat所说,在flex文件中,你应该添加
yylval = strdup(yytext);
在将您的令牌返回到 bison 文件之前。