《flex&bison》学习笔记

简记

  • wc程序可以读取多个文件,通过判断main函数参数(argc数量)来控制读取多个文件
  • √makefile写法 p20
  • 语法分析中的优先级与循环原理还待理解 p159
  • √识别注释原理 p46
  • 移进:把获取到的记号压入堆栈
  • 规约:把满足规则的所有记号弹栈 p55
  • %token <变量名> token名---------将token的值保存在<>中的变量中
  • %type <变量名> 非终结符----------将<>变量的值赋给非终结符 p59
  • 移进/规约冲突和操作符优先级 p63
  • √flex元字符 p137
  • √奇技淫巧:可已改写yyerror函数以显示错误的行号和字符/字符串

flex元字符

字符descriptionex
.匹配除换行符’\n’外所有字符
[]匹配括号内的任意字符
*匹配零个或多个紧接在前面的表达式例如a.*z匹配以a开头以z结尾的所有单词
+匹配至少一个紧接在前面的表达式
?匹配零个或一个紧接在前面的表达式-?[0-9]可匹配负数
{}前面表达式可重复次数{1,}与+的意思一致
\转义字符
()把一系列正则表达式组合在一起,+*?只影响其左边表达式(ab|cd)?ef
|匹配前面或后面的正则表达式twelve|12匹配这俩
“…”根据字面意思匹配引号内的字符除了反义字符
/匹配斜线前的表达式但是要求斜线后紧跟一表达式0/1只会匹配01中的0不会匹配02中的0
^作为正则表达式的首字符时匹配一行的开始;也被用于方括号中代表补集,其他情况无特殊含义
$作为正则表达式的最后一字符时匹配一行的结束,其他情况无特殊意义在表达式末尾与/\n有相同意义
<<EOF>>特殊模式匹配文件末尾

flex&bison的makefile写法

例:

calc: calc.l calc.y
    flex calc.l
    bison -d calc.y
    cc -o $@ calc.tab.c lex.yy.c -lfl

$@是Makefile的自动化变量,代表目标文件calc

匹配c/c++代码注释

例:

%%
"/*"                    { BEGIN(COMMENT); }
<COMMENT>"*/"           { BEGIN(INITIAL); }
<COMMENT>([^*]|\N)+|.
<COMMENT><<EOF>>        { printf("%s:%d Unterminated comment\n",curfilename,yylineno);return 0;}
"//".*\n

%parse-param

通常调用yyparse()函数是不需要参数的,但是如果需要从其他程序中导入一些信息,可以使用全局变量:

%parse-param {char *modulename}
%parse-param {int intensity}
...

这样就可以直接调用yyparse(“modulename”,num)来使用,将全局变量作为参数导入语法分析器。

改写yyerror函数以显示错误的行号和字符/字符串

void yyerror(char *);
extern char* yytext;
extern int yylineno;
void yyerror(char *s) {
    printf("%d: %s at %s\n",yylineno,s,yytext);
}

规则部分的动作

动作(action)是bison匹配语法中一条规则执行时的C代码,必须是C语言的复合语句,例:

date: month '/' day '/' year { printf("date found"); } ;
date: month '/' day '/' year { printf("date %d-%d-%d",$1,$2,$3); } ;

没有语义的规则使用默认动作:

{ $$ = $1; }

递归规则

主要规则只要记住任何递归规则或者交互递归规则组里的每个规则都必须至少有一条非递归的分支(不指向自身)。
bison处理左递归比右递归有效率(所以基本上只用左递归就可以了)

*个人理解的一些移进规约

例程:

%%
command : exp                   {printf("%d/n",$1);}
        | QUOTE                 {printf("this is a quote\n");}
;
exp: exp PLUS term              {$$ = $1 + $3;}
    |exp MINUS term             {$$ = $1 - $3;}
    |term                       {$$ = $1;}
;
term : term TIMES factor        {$$ = $1 * $3;}
    |term DIVIDE factor         {$$ = $1/$3;}
    |factor                     {$$ = $1;}
;
factor : INTEGER                {$$ = $1;}
    | LP exp RP                 {$$ = $2;}
;
%%
  1. 输入: 3 + 5
    移进 3(number) > INTEGER
    规约 INTEGER > factor > term > exp
    移进 +(plus) > PLUS
    规约 PLUS
    移进 5
    规约 INTEGER > factor > term
    规约 exp PLUS term > exp > command
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

gowinLee

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值