编写yacc文法,使其对下述文件: int fun (int a,int b) { int c=a+b; return c; } int c ; void fun(void) { int k[4; int d; int e; int f; int g; d=(3+2 ; e=3+ ; f=3 * ; g=3+2; g=3+2 } void fun(int fa,int fb[]) { return; void fun(void) { } int fun(int h) { if(h=1) return fun(2,3); else return (2*3); while(h!=1) return (c-1); } 能汇编成下述文件: INT ID ( INT ID , INT ID ) { INT ID = ID + ID ; RETURN ID ; } INT ID ; VOID ID ( VOID ) { INT ID [ NUMBER ; 【<<Error>>|缺少']'】 INT ID ; INT ID; INT ID; ID = ( NUMBER + NUMBER ; 【<<Error>>|缺少')'】 ID = NUMBER + ; 【<<Error>>|缺少操作数】 ID = NUMBER + NUMBER ) 【<<Error>>|缺少'('】; ID = NUMBER * ; 【<<Error>>|缺少操作数】 ID = NUMBER + NUMBER ; ID = NUMBER + NUMBER ) 【<<Error>>|缺少';'】 } VOID ID ( INT ID , INT ID [ ] ) { RETURN ; 【<<Error>>|缺少'}'】 VOID ID ( VOID ) { } 【<<Error>>|缺少操作数】 INT ID ( INT ID ) { IF ( ID = NUMBER ) RETURN ID ( NUMBER , NUMBER ) ; ELSE RETURN ( NUMBER * NUMBER ) ; WHILE ( ID != NUMBER ) RETURN ( ID - NUMBER ) ; }
时间: 2024-01-15 10:03:33 浏览: 128
为了将给定的文件汇编成所需的形式,我们需要编写一些规则。这些规则将告诉 Yacc 如何解析输入文件并生成汇编代码。以下是一个可能的解决方案:
```
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int lineno = 1;
%}
%token INT ID VOID IF ELSE RETURN WHILE NUMBER
%%
program:
| program external_declaration
;
external_declaration:
declaration
| function_definition
;
declaration:
INT ID ';'
;
function_definition:
type_specifier ID '(' parameter_list ')' compound_statement
;
type_specifier:
INT
| VOID
;
parameter_list:
parameter_declaration
| parameter_list ',' parameter_declaration
;
parameter_declaration:
type_specifier ID
| type_specifier ID '[' ']'
;
compound_statement:
'{' '}'
| '{' statement_list '}'
;
statement_list:
statement
| statement_list statement
;
statement:
expression_statement
| compound_statement
| selection_statement
| iteration_statement
;
expression_statement:
';'
| expression ';'
;
selection_statement:
IF '(' expression ')' statement
| IF '(' expression ')' statement ELSE statement
;
iteration_statement:
WHILE '(' expression ')' statement
;
expression:
assignment_expression
| expression ',' assignment_expression
;
assignment_expression:
equality_expression
| unary_expression '=' assignment_expression
;
equality_expression:
relational_expression
| equality_expression '==' relational_expression
| equality_expression '!=' relational_expression
;
relational_expression:
additive_expression
| relational_expression '<' additive_expression
| relational_expression '>' additive_expression
;
additive_expression:
multiplicative_expression
| additive_expression '+' multiplicative_expression
| additive_expression '-' multiplicative_expression
;
multiplicative_expression:
unary_expression
| multiplicative_expression '*' unary_expression
| multiplicative_expression '/' unary_expression
;
unary_expression:
postfix_expression
| '-' unary_expression
;
postfix_expression:
primary_expression
| postfix_expression '[' expression ']'
| postfix_expression '(' ')'
| postfix_expression '(' argument_expression_list ')'
;
primary_expression:
ID
| NUMBER
| '(' expression ')'
;
argument_expression_list:
assignment_expression
| argument_expression_list ',' assignment_expression
;
%%
int main() {
yyparse();
return 0;
}
void yyerror(char *s) {
fprintf(stderr, "line %d: %s\n", lineno, s);
}
int yywrap() {
return 1;
}
```
这是一个非常基本的 Yacc 规则集,它定义了语言的各个部分。您需要将此代码保存到名为 `grammar.y` 的文件中。
接下来,我们需要创建一个名为 `lex.l` 的新文件,其中包含与语法规则匹配的词汇表。
```
%{
#include "y.tab.h"
%}
%%
"int" { return INT; }
"void" { return VOID; }
"if" { return IF; }
"else" { return ELSE; }
"return" { return RETURN; }
"while" { return WHILE; }
[0-9]+ { yylval.num = atoi(yytext); return NUMBER; }
[a-zA-Z][a-zA-Z0-9]*{ yylval.str = strdup(yytext); return ID; }
"[" { return '['; }
"]" { return ']'; }
"(" { return '('; }
")" { return ')'; }
";" { return ';'; }
"{" { return '{'; }
"}" { return '}'; }
"+" { return '+'; }
"-" { return '-'; }
"*" { return '*'; }
"/" { return '/'; }
"==" { return EQ; }
"!=" { return NE; }
"<" { return '<'; }
">" { return '>'; }
"=" { return '='; }
"," { return ','; }
[ \t\n] { /* ignore whitespace */ }
. { printf("Unknown token: %s\n", yytext); }
%%
int main() {
yyparse();
return 0;
}
void yyerror(char *s) {
fprintf(stderr, "line %d: %s\n", yylineno, s);
}
int yywrap() {
return 1;
}
```
请注意,此文件包含与 `y.tab.h` 匹配的标头文件,并且包含了一些正则表达式以匹配输入文件中的单词。您需要将此文件保存为 `lex.l`。同时,还需要生成一个头文件 `y.tab.h`,这可以通过在终端中执行以下命令来完成:
```
yacc -d grammar.y
```
最后,我们需要生成一个可执行文件并测试它是否按预期工作。这可以通过在终端中执行以下命令来完成:
```
yacc -d grammar.y
lex lex.l
cc y.tab.c lex.yy.c -o compiler
./compiler < input.txt
```
其中,`input.txt` 是您想要编译的输入文件。如果一切正常,您将会看到输出文件的内容显示在终端上。
阅读全文