使用lex,yacc实现C语言的词法分析、语法分析,最后输出抽象语法树(AST),不要求typedef,#define复杂语法,给出完整详细的lex代码和yacc代码
时间: 2024-05-09 08:15:47 浏览: 81
c语言编译器,用lex和yacc工具完成词法分析与语法分析并生成语法树
5星 · 资源好评率100%
由于代码比较长,我将分为两个部分分别给出。
首先是lex代码:
```
%{
#include "y.tab.h"
%}
%%
"int" { return INT; }
"float" { return FLOAT; }
"char" { return CHAR; }
"void" { return VOID; }
"if" { return IF; }
"else" { return ELSE; }
"while" { return WHILE; }
"return"{ return RETURN; }
"for" { return FOR; }
[a-zA-Z_][a-zA-Z0-9_]* { yylval.strval = strdup(yytext); return ID; }
[0-9]+"."[0-9]* { yylval.fval = atof(yytext); return FLOAT_CONST; }
[0-9]+ { yylval.ival = atoi(yytext); return INT_CONST; }
\"(\\.|[^\\"])*\" { yylval.strval = strdup(yytext); return STRING_CONST; }
\'(\\.|[^\\'])\' { yylval.chval = yytext[1]; return CHAR_CONST; }
"==" { return EQ; }
"!=" { return NEQ; }
"<=" { return LE; }
">=" { return GE; }
"&&" { return AND; }
"||" { return OR; }
"++" { return INC; }
"--" { return DEC; }
"+" { return PLUS; }
"-" { return MINUS; }
"*" { return MUL; }
"/" { return DIV; }
"%" { return MOD; }
"=" { return ASSIGN; }
">" { return GT; }
"<" { return LT; }
"!" { return NOT; }
"&" { return BIT_AND; }
"^" { return BIT_XOR; }
"|" { return BIT_OR; }
"~" { return BIT_NOT; }
"<<" { return LEFT_SHIFT; }
">>" { return RIGHT_SHIFT; }
";" { return SEMICOLON; }
"," { return COMMA; }
"(" { return LPAREN; }
")" { return RPAREN; }
"[" { return LBRACKET; }
"]" { return RBRACKET; }
"{" { return LBRACE; }
"}" { return RBRACE; }
"?" { return QUESTION; }
":" { return COLON; }
"#" { return HASH; }
[ \t\n]+ { /* ignore white space */ }
. { printf("Unrecognized character %s\n", yytext); }
%%
int yywrap() { return 1; }
```
接下来是yacc代码:
```
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int yylex();
void yyerror(char *s);
extern char *yytext;
extern int yylineno;
extern FILE *yyin;
%}
%token INT FLOAT CHAR VOID IF ELSE WHILE FOR RETURN
%token ID FLOAT_CONST INT_CONST STRING_CONST CHAR_CONST
%token EQ NEQ LE GE AND OR INC DEC
%token PLUS MINUS MUL DIV MOD ASSIGN LT GT NOT
%token BIT_AND BIT_OR BIT_XOR BIT_NOT LEFT_SHIFT RIGHT_SHIFT
%token SEMICOLON COMMA LPAREN RPAREN LBRACKET RBRACKET LBRACE RBRACE
%token QUESTION COLON HASH
%left OR
%left AND
%nonassoc EQ NEQ
%left LT GT LE GE
%left PLUS MINUS
%left MUL DIV MOD
%right NOT BIT_NOT INC DEC
%left LEFT_SHIFT RIGHT_SHIFT
%left BIT_AND
%left BIT_XOR
%left BIT_OR
%left QUESTION COLON
%right ASSIGN
%%
program:
external_declaration
| program external_declaration
;
external_declaration:
type_specifier ID SEMICOLON
| type_specifier ID LPAREN parameter_list RPAREN compound_statement
| type_specifier ID LPAREN RPAREN compound_statement
| type_specifier ID LBRACKET INT_CONST RBRACKET SEMICOLON
| type_specifier ID LBRACKET RBRACKET SEMICOLON
;
type_specifier:
INT
| FLOAT
| CHAR
| VOID
;
parameter_list:
parameter_declaration
| parameter_list COMMA parameter_declaration
;
parameter_declaration:
type_specifier ID
;
compound_statement:
LBRACE statement_list RBRACE
;
statement_list:
statement
| statement_list statement
;
statement:
expression_statement
| compound_statement
| selection_statement
| iteration_statement
| jump_statement
;
expression_statement:
SEMICOLON
| expression SEMICOLON
;
selection_statement:
IF LPAREN expression RPAREN statement
| IF LPAREN expression RPAREN statement ELSE statement
;
iteration_statement:
WHILE LPAREN expression RPAREN statement
| FOR LPAREN expression_statement expression_statement RPAREN statement
;
jump_statement:
RETURN SEMICOLON
| RETURN expression SEMICOLON
;
expression:
assignment_expression
;
assignment_expression:
logical_or_expression
| logical_or_expression ASSIGN assignment_expression
;
logical_or_expression:
logical_and_expression
| logical_or_expression OR logical_and_expression
;
logical_and_expression:
bitwise_or_expression
| logical_and_expression AND bitwise_or_expression
;
bitwise_or_expression:
bitwise_xor_expression
| bitwise_or_expression BIT_OR bitwise_xor_expression
;
bitwise_xor_expression:
bitwise_and_expression
| bitwise_xor_expression BIT_XOR bitwise_and_expression
;
bitwise_and_expression:
equality_expression
| bitwise_and_expression BIT_AND equality_expression
;
equality_expression:
relational_expression
| equality_expression EQ relational_expression
| equality_expression NEQ relational_expression
;
relational_expression:
shift_expression
| relational_expression LT shift_expression
| relational_expression GT shift_expression
| relational_expression LE shift_expression
| relational_expression GE shift_expression
;
shift_expression:
additive_expression
| shift_expression LEFT_SHIFT additive_expression
| shift_expression RIGHT_SHIFT additive_expression
;
additive_expression:
multiplicative_expression
| additive_expression PLUS multiplicative_expression
| additive_expression MINUS multiplicative_expression
;
multiplicative_expression:
unary_expression
| multiplicative_expression MUL unary_expression
| multiplicative_expression DIV unary_expression
| multiplicative_expression MOD unary_expression
;
unary_expression:
postfix_expression
| INC unary_expression
| DEC unary_expression
| NOT unary_expression
| BIT_NOT unary_expression
| PLUS unary_expression
| MINUS unary_expression
;
postfix_expression:
primary_expression
| postfix_expression LBRACKET expression RBRACKET
| postfix_expression LPAREN RPAREN
| postfix_expression LPAREN argument_expression_list RPAREN
| postfix_expression INC
| postfix_expression DEC
;
argument_expression_list:
assignment_expression
| argument_expression_list COMMA assignment_expression
;
primary_expression:
ID
| INT_CONST
| FLOAT_CONST
| CHAR_CONST
| STRING_CONST
| LPAREN expression RPAREN
;
%%
void yyerror(char *s) {
printf("%s at line %d\n", s, yylineno);
}
int main(int argc, char *argv[]) {
if (argc < 2) {
printf("Usage: %s filename.c\n", argv[0]);
return 1;
}
FILE *fp = fopen(argv[1], "r");
if (!fp) {
printf("Error opening file %s\n", argv[1]);
return 1;
}
yyin = fp;
yyparse();
fclose(fp);
return 0;
}
```
阅读全文