ANSI C的LEX、YACC的描述文件

/*below is Yacc Grammer source for ANSI C*/

/*YACC--LALR(1) PARSER*/

%token IDENTIFIER CONSTANT STRING_LITERAL SIZEOF
%token PTR_OP INC_OP DEC_OP LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP
%token AND_OP OR_OP MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN
%token SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN
%token XOR_ASSIGN OR_ASSIGN TYPE_NAME

%token TYPEDEF EXTERN STATIC AUTO REGISTER
%token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID
%token STRUCT UNION ENUM ELIPSIS RANGE

%token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN

%start file
%%

primary_expr
: identifier
| CONSTANT
| STRING_LITERAL
| '(' expr ')'
;

postfix_expr
: primary_expr
| postfix_expr '[' expr ']'
| postfix_expr '(' ')'
| postfix_expr '(' argument_expr_list ')'
| postfix_expr '.' identifier
| postfix_expr PTR_OP identifier
| postfix_expr INC_OP
| postfix_expr DEC_OP
;

argument_expr_list
: assignment_expr
| argument_expr_list ',' assignment_expr
;

unary_expr
: postfix_expr
| INC_OP unary_expr
| DEC_OP unary_expr
| unary_operator cast_expr
| SIZEOF unary_expr
| SIZEOF '(' type_name ')'
;

unary_operator
: '&'
| '*'
| '+'
| '-'
| '~'
| '!'
;

cast_expr
: unary_expr
| '(' type_name ')' cast_expr
;

multiplicative_expr
: cast_expr
| multiplicative_expr '*' cast_expr
| multiplicative_expr '/' cast_expr
| multiplicative_expr '%' cast_expr
;

additive_expr
: multiplicative_expr
| additive_expr '+' multiplicative_expr
| additive_expr '-' multiplicative_expr
;

shift_expr
: additive_expr
| shift_expr LEFT_OP additive_expr
| shift_expr RIGHT_OP additive_expr
;

relational_expr
: shift_expr
| relational_expr '<' shift_expr
| relational_expr '>' shift_expr
| relational_expr LE_OP shift_expr
| relational_expr GE_OP shift_expr
;

equality_expr
: relational_expr
| equality_expr EQ_OP relational_expr
| equality_expr NE_OP relational_expr
;

and_expr
: equality_expr
| and_expr '&' equality_expr
;

exclusive_or_expr
: and_expr
| exclusive_or_expr '^' and_expr
;

inclusive_or_expr
: exclusive_or_expr
| inclusive_or_expr '|' exclusive_or_expr
;

logical_and_expr
: inclusive_or_expr
| logical_and_expr AND_OP inclusive_or_expr
;

logical_or_expr
: logical_and_expr
| logical_or_expr OR_OP logical_and_expr
;

conditional_expr
: logical_or_expr
| logical_or_expr '?' logical_or_expr ':' conditional_expr
;

assignment_expr
: conditional_expr
| unary_expr assignment_operator assignment_expr
;

assignment_operator
: '='
| MUL_ASSIGN
| DIV_ASSIGN
| MOD_ASSIGN
| ADD_ASSIGN
| SUB_ASSIGN
| LEFT_ASSIGN
| RIGHT_ASSIGN
| AND_ASSIGN
| XOR_ASSIGN
| OR_ASSIGN
;

expr
: assignment_expr
| expr ',' assignment_expr
;

constant_expr
: conditional_expr
;

declaration
: declaration_specifiers ';'
| declaration_specifiers init_declarator_list ';'
;

declaration_specifiers
: storage_class_specifier
| storage_class_specifier declaration_specifiers
| type_specifier
| type_specifier declaration_specifiers
;

init_declarator_list
: init_declarator
| init_declarator_list ',' init_declarator
;

init_declarator
: declarator
| declarator '=' initializer
;

storage_class_specifier
: TYPEDEF
| EXTERN
| STATIC
| AUTO
| REGISTER
;

type_specifier
: CHAR
| SHORT
| INT
| LONG
| SIGNED
| UNSIGNED
| FLOAT
| DOUBLE
| CONST
| VOLATILE
| VOID
| struct_or_union_specifier
| enum_specifier
| TYPE_NAME
;

struct_or_union_specifier
: struct_or_union identifier '{ ' struct_declaration_list ' }'
| struct_or_union '{ ' struct_declaration_list ' }'
| struct_or_union identifier
;

struct_or_union
: STRUCT
| UNION
;

struct_declaration_list
: struct_declaration
| struct_declaration_list struct_declaration
;

struct_declaration
: type_specifier_list struct_declarator_list ';'
;

struct_declarator_list
: struct_declarator
| struct_declarator_list ',' struct_declarator
;

struct_declarator
: declarator
| ':' constant_expr
| declarator ':' constant_expr
;

enum_specifier
: ENUM '{ ' enumerator_list ' }'
| ENUM identifier '{ ' enumerator_list ' }'
| ENUM identifier
;

enumerator_list
: enumerator
| enumerator_list ',' enumerator
;

enumerator
: identifier
| identifier '=' constant_expr
;

declarator
: declarator2
| pointer declarator2
;

declarator2
: identifier
| '(' declarator ')'
| declarator2 '[' ']'
| declarator2 '[' constant_expr ']'
| declarator2 '(' ')'
| declarator2 '(' parameter_type_list ')'
| declarator2 '(' parameter_identifier_list ')'
;

pointer
: '*'
| '*' type_specifier_list
| '*' pointer
| '*' type_specifier_list pointer
;

type_specifier_list
: type_specifier
| type_specifier_list type_specifier
;

parameter_identifier_list
: identifier_list
| identifier_list ',' ELIPSIS
;

identifier_list
: identifier
| identifier_list ',' identifier
;

parameter_type_list
: parameter_list
| parameter_list ',' ELIPSIS
;

parameter_list
: parameter_declaration
| parameter_list ',' parameter_declaration
;

parameter_declaration
: type_specifier_list declarator
| type_name
;

type_name
: type_specifier_list
| type_specifier_list abstract_declarator
;

abstract_declarator
: pointer
| abstract_declarator2
| pointer abstract_declarator2
;

abstract_declarator2
: '(' abstract_declarator ')'
| '[' ']'
| '[' constant_expr ']'
| abstract_declarator2 '[' ']'
| abstract_declarator2 '[' constant_expr ']'
| '(' ')'
| '(' parameter_type_list ')'
| abstract_declarator2 '(' ')'
| abstract_declarator2 '(' parameter_type_list ')'
;

initializer
: assignment_expr
| '{ ' initializer_list ' }'
| '{ ' initializer_list ',' ' }'
;

initializer_list
: initializer
| initializer_list ',' initializer
;

statement
: labeled_statement
| compound_statement
| expression_statement
| selection_statement
| iteration_statement
| jump_statement
;

labeled_statement
: identifier ':' statement
| CASE constant_expr ':' statement
| DEFAULT ':' statement
;

compound_statement
: '{ ' ' }'
| '{ ' statement_list ' }'
| '{ ' declaration_list ' }'
| '{ ' declaration_list statement_list ' }'
;

declaration_list
: declaration
| declaration_list declaration
;

statement_list
: statement
| statement_list statement
;

expression_statement
: ';'
| expr ';'
;

selection_statement
: IF '(' expr ')' statement
| IF '(' expr ')' statement ELSE statement
| SWITCH '(' expr ')' statement
;

iteration_statement
: WHILE '(' expr ')' statement
| DO statement WHILE '(' expr ')' ';'
| FOR '(' ';' ';' ')' statement
| FOR '(' ';' ';' expr ')' statement
| FOR '(' ';' expr ';' ')' statement
| FOR '(' ';' expr ';' expr ')' statement
| FOR '(' expr ';' ';' ')' statement
| FOR '(' expr ';' ';' expr ')' statement
| FOR '(' expr ';' expr ';' ')' statement
| FOR '(' expr ';' expr ';' expr ')' statement
;

jump_statement
: GOTO identifier ';'
| CONTINUE ';'
| BREAK ';'
| RETURN ';'
| RETURN expr ';'
;

file
: external_definition
| file external_definition
;

external_definition
: function_definition
| declaration
;

function_definition
: declarator function_body
| declaration_specifiers declarator function_body
;

function_body
: compound_statement
| declaration_list compound_statement
;

identifier
: IDENTIFIER
;
%%

#include <stdio.h>

extern char yytext[];
extern int column;

yyerror(s)
char *s;
{
fflush(stdout);
printf("/n%*s/n%*s/n", column, "^", column, s);
}

main()
{
int yyparse();

return(yyparse());
}
/Rogue/Monster/
else
 echo "will not over write ./main.c"
fi
if `test ! -s ./scan.l`
then
echo "writting ./scan.l"
cat > ./scan.l << '/Rogue/Monster/'
D   [0-9]
L   [a-zA-Z_]
H   [a-fA-F0-9]
E   [Ee][+-]?{ D }+
FS   (f|F|l|L)
IS   (u|U|l|L)*

%{
#include <stdio.h>
#include "y.tab.h"

void count();
% }

%%
"/*"   { comment(); }

"auto"   { count(); return(AUTO); }
"break"   { count(); return(BREAK); }
"case"   { count(); return(CASE); }
"char"   { count(); return(CHAR); }
"const"   { count(); return(CONST); }
"continue"  { count(); return(CONTINUE); }
"default"  { count(); return(DEFAULT); }
"do"   { count(); return(DO); }
"double"  { count(); return(DOUBLE); }
"else"   { count(); return(ELSE); }
"enum"   { count(); return(ENUM); }
"extern"  { count(); return(EXTERN); }
"float"   { count(); return(FLOAT); }
"for"   { count(); return(FOR); }
"goto"   { count(); return(GOTO); }
"if"   { count(); return(IF); }
"int"   { count(); return(INT); }
"long"   { count(); return(LONG); }
"register"  { count(); return(REGISTER); }
"return"  { count(); return(RETURN); }
"short"   { count(); return(SHORT); }
"signed"  { count(); return(SIGNED); }
"sizeof"  { count(); return(SIZEOF); }
"static"  { count(); return(STATIC); }
"struct"  { count(); return(STRUCT); }
"switch"  { count(); return(SWITCH); }
"typedef"  { count(); return(TYPEDEF); }
"union"   { count(); return(UNION); }
"unsigned"  { count(); return(UNSIGNED); }
"void"   { count(); return(VOID); }
"volatile"  { count(); return(VOLATILE); }
"while"   { count(); return(WHILE); }

{ L }({ L }|{ D })*  { count(); return(check_type()); }

0[xX]{ H }+{ IS }?  { count(); return(CONSTANT); }
0[xX]{ H }+{ IS }?  { count(); return(CONSTANT); }
0{ D }+{ IS }?  { count(); return(CONSTANT); }
0{ D }+{ IS }?  { count(); return(CONSTANT); }
{ D }+{ IS }?  { count(); return(CONSTANT); }
{ D }+{ IS }?  { count(); return(CONSTANT); }
'(//.|[^//'])+'  { count(); return(CONSTANT); }

{ D }+{ E }{ FS }?  { count(); return(CONSTANT); }
{ D }*"."{ D }+({ E })?{ FS }? { count(); return(CONSTANT); }
{ D }+"."{ D }*({ E })?{ FS }? { count(); return(CONSTANT); }

/"(//.|[^//"])*/" { count(); return(STRING_LITERAL); }

">>="   { count(); return(RIGHT_ASSIGN); }
"<<="   { count(); return(LEFT_ASSIGN); }
"+="   { count(); return(ADD_ASSIGN); }
"-="   { count(); return(SUB_ASSIGN); }
"*="   { count(); return(MUL_ASSIGN); }
"/="   { count(); return(DIV_ASSIGN); }
"%="   { count(); return(MOD_ASSIGN); }
"&="   { count(); return(AND_ASSIGN); }
"^="   { count(); return(XOR_ASSIGN); }
"|="   { count(); return(OR_ASSIGN); }
">>"   { count(); return(RIGHT_OP); }
"<<"   { count(); return(LEFT_OP); }
"++"   { count(); return(INC_OP); }
"--"   { count(); return(DEC_OP); }
"->"   { count(); return(PTR_OP); }
"&&"   { count(); return(AND_OP); }
"||"   { count(); return(OR_OP); }
"<="   { count(); return(LE_OP); }
">="   { count(); return(GE_OP); }
"=="   { count(); return(EQ_OP); }
"!="   { count(); return(NE_OP); }
";"   { count(); return(';'); }
"{ "   { count(); return('{ '); }
" }"   { count(); return(' }'); }
","   { count(); return(','); }
":"   { count(); return(':'); }
"="   { count(); return('='); }
"("   { count(); return('('); }
")"   { count(); return(')'); }
"["   { count(); return('['); }
"]"   { count(); return(']'); }
"."   { count(); return('.'); }
"&"   { count(); return('&'); }
"!"   { count(); return('!'); }
"~"   { count(); return('~'); }
"-"   { count(); return('-'); }
"+"   { count(); return('+'); }
"*"   { count(); return('*'); }
"/"   { count(); return('/'); }
"%"   { count(); return('%'); }
"<"   { count(); return('<'); }
">"   { count(); return('>'); }
"^"   { count(); return('^'); }
"|"   { count(); return('|'); }
"?"   { count(); return('?'); }

[ /t/v/n/f]  { count(); }
.   { /* ignore bad characters */ }

%%

yywrap()
{
return(1);
}

comment()
{
char c, c1;

loop:
while ((c = input()) != '*' && c != 0)
 putchar(c);

if ((c1 = input()) != '/' && c != 0)
{
 unput(c1);
 goto loop;
}

if (c != 0)
 putchar(c1);
}

int column = 0;

void count()
{
int i;

for (i = 0; yytext[i] != '/0'; i++)
 if (yytext[i] == '/n')
  column = 0;
 else if (yytext[i] == '/t')
  column += 8 - (column % 8);
 else
  column++;

ECHO;
}

int check_type()
{
/*
* pseudo code --- this is what it should check
*
* if (yytext == type_name)
*  return(TYPE_NAME);
*
* return(IDENTIFIER);
*/

/*
* it actually will only return IDENTIFIER
*/

return(IDENTIFIER);
}
/Rogue/Monster/
else
 echo "will not over write ./scan.l"
fi
if `test ! -s ./y.tab.h`
then
echo "writting ./y.tab.h"
cat > ./y.tab.h << '/Rogue/Monster/'
# define IDENTIFIER 257
# define CONSTANT 258
# define STRING_LITERAL 259
# define SIZEOF 260
# define PTR_OP 261
# define INC_OP 262
# define DEC_OP 263
# define LEFT_OP 264
# define RIGHT_OP 265
# define LE_OP 266
# define GE_OP 267
# define EQ_OP 268
# define NE_OP 269
# define AND_OP 270
# define OR_OP 271
# define MUL_ASSIGN 272
# define DIV_ASSIGN 273
# define MOD_ASSIGN 274
# define ADD_ASSIGN 275
# define SUB_ASSIGN 276
# define LEFT_ASSIGN 277
# define RIGHT_ASSIGN 278
# define AND_ASSIGN 279
# define XOR_ASSIGN 280
# define OR_ASSIGN 281
# define TYPE_NAME 282
# define TYPEDEF 283
# define EXTERN 284
# define STATIC 285
# define AUTO 286
# define REGISTER 287
# define CHAR 288
# define SHORT 289
# define INT 290
# define LONG 291
# define SIGNED 292
# define UNSIGNED 293
# define FLOAT 294
# define DOUBLE 295
# define CONST 296
# define VOLATILE 297
# define VOID 298
# define STRUCT 299
# define UNION 300
# define ENUM 301
# define ELIPSIS 302
# define RANGE 303
# define CASE 304
# define DEFAULT 305
# define IF 306
# define ELSE 307
# define SWITCH 308
# define WHILE 309
# define DO 310
# define FOR 311
# define GOTO 312
# define CONTINUE 313
# define BREAK 314
# define RETURN 315
/Rogue/Monster/
else
 echo "will not over write ./y.tab.h"
fi
echo "Finished archive 1 of 1"
exit

|| Tom Stockfisch, UCSD Chemistry tps%chem@sdcsvax.UCSD
作者: 胡彦 本框架是一个lex/yacc完整的示例,用于学习lex/yacc程序基本的搭建方法,在linux/cygwin下敲入make就可以编译和执行。 本例子虽小却演示了lex/yacc程序最常见和重要的特征: * lex/yacc文件格式、程序结构。 * 如何在lex/yacc中使用C++和STL库,用extern "C"声明那些lex/yacc生成的、要链接的C函数,如yylex(), yywrap(), yyerror()。 * 重定义YYSTYPE/yylval为复杂类型。 * 用%token方式声明yacc记号。 * 用%type方式声明非终结符的类型。 * lex里正则表达式的定义、识别方式。 * lex里用yylval向yacc返回属性值。 * 在yacc嵌入的C代码动作里,对记号属性($1, $2等)、和非终结符属性($$)的正确引用方法。 * 对yyin/yyout重赋值,以改变yacc默认的输入/输出目标。 * 如何开始解析(yyparse函数),结束或继续解析(yywrap函数)。 本例子功能是,对当前目录下的file.txt文件,解析出其中的标识符、数字、其它符号,显示在屏幕上。linux调试环境是Ubuntu 10.04。 总之,大部分框架已经搭好了,你只要稍加扩展就可以成为一个计算器之类的程序,用于《编译原理》的课程设计。 文件列表: lex.l: lex程序文件yacc.y: yacc程序文件。 main.hpp: 共同使用的头文件。 Makefile: makefile文件。 file.txt: 给程序解析的文本文件。 使用方法: 1-把lex_yacc_example.rar解压到linux/cygwin下。 2-命令行进入lex_yacc_example目录。 3-敲入make,这时会自动执行以下操作: (1) 自动调用flex编译.l文件,生成lex.yy.c文件。 (2) 自动调用bison编译.y文件,生成yacc.tab.c和yacc.tab.h文件。 (3) 自动调用g++编译、链接出可执行文件main。 (4) 自动执行main,得到如下结果:。 bison -d yacc.y g++ -c lex.yy.c g++ -c yacc.tab.c g++ lex.yy.o yacc.tab.o -o main id: abc id: defghi int: 123 int: 45678 op: ! op: @ op: # op: $ AllId: abc defghi 参考资料:《LexYacc从入门到精通(6)-解析C-C++包含文件》, http://blog.csdn.net/pandaxcl/article/details/1321552 其它文章和代码请留意我的blog: http://blog.csdn.net/huyansoft 2013-4-27
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值