C編譯器LEX 和 YACC輸入原始檔。 (轉)

worldblog發表於2007-12-10
C編譯器LEX 和 YACC輸入原始檔。 (轉)[@more@]

/*below is Yacc Grammer for ANSI C*/

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

%token NTIFIER 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 ' | 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
 | ion_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

extern char yytext[];
extern int column;

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

main()
{
 int yyparse();

 return(yyparse());
}
RogueMonster
else
  echo "will not over write ./main.c"
fi
if `test ! -s ./scan.l`
then
echo "writting ./scan.l"
cat > ./scan.l << 'RogueMonster'
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
#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(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('?'); }

[ tvnf] { count(); }
. { /* ignore bad characters */ }

%%

yywrap()
{
 return(1);
}

comment()
{
 char c, c1;

l:
 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] != ''; 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);
}
RogueMonster
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 << 'RogueMonster'
# 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
RogueMonster
else
  echo "will not over write ./y.tab.h"
fi
echo "Finished archive 1 of 1"
exit

|| Tom Stockfisch, UCSD Chemistry to:tps%chem@sdcsvax.UCSD">tps%chem@sdcsvax.UCSD

 


 


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-990800/,如需轉載,請註明出處,否則將追究法律責任。

相關文章