YACC基本用法
... rules ...
%%
%token INTEGER
#ifndef YYSTYPE
#define YYSTYPE int
#endif
#define INTEGER 258
extern YYSTYPE yylval;
[0-9]+ {
yylval = atoi(yytext);
return INTEGER;
}
[-+] return *yytext; /* return operator */
返回加号或减号。注意要把减号放在前面,避免被认作是范围符号。
%left ‘+’ ‘-‘
%left ‘*’ ‘/’
上面定义的乘法和除法比加法和减法有更高的优先级。
%union
int iValue; /* integer value */
char sIndex; /* symbol table index */
nodeType *nPtr; /* node pointer */
};
typedef union
int iValue; /* integer value */
char sIndex; /* symbol table index */
nodeType *nPtr; /* node pointer */
} YYSTYPE;
extern YYSTYPE yylval;
%token <iValue> INTEGER
%type <nPtr> expr
把expr绑定到nPtr,把INTEGER绑定到iValue。yacc处理时会做转换。如:
expr: INTEGER { $$ = con($1); }
转换结果为:
yylval.nPtr = con(yyvsp[0].iValue);
其中yyvsp[0]是值栈(value stack)当前的头部。
%left GE LE EQ NE '>' '<'
%left '+' '-'
%left '*'
%nonassoc UMINUS
%nonassoc的含义是没有结合性。它一般与%prec结合使用表示该操作有同样的优先级。如:
expr: '-' expr %prec UMINUS { $$ = node(UMINUS, 1, $2); }
表示该操作的优先级与UMINUS相同,在上面的定义中,UMINUS的优先级高于其他操作符,所以该操作的优先级也高于其他操作符计算。
%token INTEGER
%%
program: program expr '\n' { printf("%d\n", $2); }
;
expr: INTEGER {
| expr '+' expr {
= $1 + $3; }
| expr '-' expr { $$ = $1 - $3; }
;
%%
int yyerror(char *s)
{
fprintf(stderr, "%s\n", s);
return 0;
}
{
yyparse();
return 0;
}
list: item
| list ',' item;
list: item
| item ',' list
%nonassoc IFX
%nonassoc ELSE
stmt: IF expr stmt %prec IFX
| IF expr stmt ELSE stmt
(1)终端符名全部用大写字母,非终端符全部用小写字母;
(2)把语法规则和语义动作放在不同的行;
(3)把左部相同的规则写在一起,左部只写一次,而后面所有规则都写在竖线“|”之后;
(4)把分号“;”放在规则最后,独占一行;
(5)用制表符来对齐规则和动作。
Yacc处理错误的方法是:当发现语法错误时,yacc丢掉那些导致错误的符号适当调整状态栈。然后从出错处的后一个符号处或跳过若干符号直到遇到用户指定的某个符号时开始继续分析。Yacc内部有一个保留的终结符error,把它写在某个产生式的右部,则Yacc就认为这个地方可能发生错误,当语法分析的确在这里发生错误时,Yacc就用上面介绍的方法处理,如果没有用到 error的产生式,则 Yacc打印出“Syntax error”,就终止语法分析。
stat: error
;
使yacc在分析stat推导出的句型时,遇到语法错误时跳过出错的部分,继续分析(也会打印语法错误信息)
stat: error ';'
;
使yacc碰到语法错时,跳过输入串直到碰到下一个分号才继续开始语法分析。
//L文件:
%{
#include "FIRST_TA.H"
#include <stdio.h>
#include <stdlib.h>
%}
%%
a {return A_STATE;}
b {return B_STATE;}
c {return C_STATE;}
not {return NOT;}
%% //Y文件:
%{
#include <stdio.h>
#include <stdlib.h>
%}
%token A_STATE B_STATE C_STATE NOT
%% program :
A_STATE B_STATE {
int c, d;
c = ;
d = ;
}
c_state_not {
int e,f;
e = ;
f = ;
}
|
A_STATE B_STATE {
int a, b;
a = ;
b = ;
}
c_state_not : C_STATE NOT{}
%% 输入文件的字符:a, b, c, f, c, not
YACC基本用法的更多相关文章
- 【译】Python Lex Yacc手册
本文是PLY (Python Lex-Yacc)的中文翻译版.转载请注明出处.这里有更好的阅读体验. 如果你从事编译器或解析器的开发工作,你可能对lex和yacc不会陌生,PLY是David Beaz ...
- qmake理解(还可以加入Lex Yacc文件)
关于qmake,好一段时间令我一头雾水,不知道用来干嘛的,只知道怎么用,而且也只懂那么一两个命令,详细看过资料以后整理如下: 1.首先,感性的认识是,qmake可以利用源文件(包括头文件h,实现文件c ...
- Lex Yacc手册
Python Lex Yacc手册 本文是PLY (Python Lex-Yacc)的中文翻译版.转载请注明出处.这里有更好的阅读体验. 如果你从事编译器或解析器的开发工作,你可能对lex和yacc不 ...
- 【转】BNF和EBNF的含义与用法
[转]BNF和EBNF的含义与用法 BNF 和EBNF的含义与用法 1简介 关于本文 什么是BNF?工作原理 基本原理 一个实例 EBNF及其用途 ...
- VIM+ctags+cscope用法
使用vim + cscope/ctags,就能够实现Source Insight的功能,可以很方便地查看分析源代码. 关键词: vim, cscope, ctags, tags 1. 查看vi ...
- EditText 基本用法
title: EditText 基本用法 tags: EditText,编辑框,输入框 --- EditText介绍: EditText 在开发中也是经常用到的控件,也是一个比较必要的组件,可以说它是 ...
- jquery插件的用法之cookie 插件
一.使用cookie 插件 插件官方网站下载地址:http://plugins.jquery.com/cookie/ cookie 插件的用法比较简单,直接粘贴下面代码示例: //生成一个cookie ...
- Java中的Socket的用法
Java中的Socket的用法 Java中的Socket分为普通的Socket和NioSocket. 普通Socket的用法 Java中的 ...
- [转载]C#中MessageBox.Show用法以及VB.NET中MsgBox用法
一.C#中MessageBox.Show用法 MessageBox.Show (String) 显示具有指定文本的消息框. 由 .NET Compact Framework 支持. MessageBo ...
随机推荐
- [Linked List]Insertion Sort List
Total Accepted: 59422 Total Submissions: 213019 Difficulty: Medium Sort a linked list using insertio ...
- C与C++
有幸在某网站发现这篇文章,读罢,觉得蛮有道理,发来大家一起共勉之! 总是被同学们问到,如何学习C和C++才不茫然,才不是乱学,想了一下,这里给出一个总的回复. 一家之言,欢迎拍砖哈. 1.可以考虑先学 ...
- JS delete 用法(删除对象属性及变量)
1,对象属性删除 function fun(){ this.name = 'mm'; } var obj = new fun(); console.log(obj.name);//mm delete ...
- CentOS6.5下Mysql数据库的安装与配置
一.mysql简介 说到数据库,我们大多想到的是关系型数据库,比如mysql.oracle.sqlserver等等,这些数据库软件在windows上安装都非常的方便,在Linux上如果要安装数据库,咱 ...
- gnome-ssh-askpass:No such file or directory && unable to read askpass response
1.使用git的时候,gnome-ssh-askpass出现“error: cannot run /usr/libexec/openssh/gnome-ssh-askpass: No such fil ...
- android Xml生成一条细线,以及获取屏幕宽度和高度
<View android:layout_width="match_parent" android:layout_height="2dip" androi ...
- python学习day7
目录 一.反射 二.socket 三.socketserver 一.反射 python中的反射功能是由以下四个内置函数提供:hasattr.getattr.setattr.delattr,改四个函数分 ...
- [Django 1.5] jQuery/Ajax 在Django使用 ,如何更新模板里里变量
最近希望实现一个页面局部刷新的功能,于是开始查阅ajax资料.幸好现在ajax很多功能都封装在jQuery这个库里面,我们可以很方便去调用.通过学习几个简单的小例子,可以实现简单的前端代码更新,还有重 ...
- MySQL_数据分页查询(limit用法)
取前5条数据 select * from table_name limit 0,5 或 select * from table_name limit 5 取第11条到第15条数据,共5条 select ...
- JDBC批量操作
/** * 批量执行预定义模式的SQL */ public static void exeBatchParparedSQL() { ...