fprintf(stderr, "Usage: %s filename\n", argv[0]);怎么理解
时间: 2024-04-02 14:31:35 浏览: 18
这是一个 C 语言中的语句,作用是向标准错误输出流(stderr)打印一条提示消息,提示用户正确使用程序的方法。具体来说,这条语句使用了 fprintf 函数,它的第一个参数是输出流,第二个参数是格式化字符串,第三个参数及以后是可变参数,用于替换格式化字符串中的占位符。其中,格式化字符串中的 "%s" 表示一个字符串类型的占位符,它将会被后面的 argv[0] 所替换,这个变量存储了程序的名称。因此,整条语句的含义就是:输出一条错误消息,提示用户正确使用程序的方法,其中包括程序的名称。
相关问题
使用c语言编写PL/0编译程序的语法分析程序
PL/0语言的语法分析一般使用LL(1)文法进行分析,下面是使用C语言编写的PL/0编译程序的语法分析程序的基本框架:
```c
/* PL/0语言的语法分析程序 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* 定义PL/0语言的语法规则 */
/* 定义词法分析器的返回类型 */
typedef enum {
IDENT, NUMBER, PLUS, MINUS, TIMES, SLASH,
ODD, EQL, NEQ, LSS, LEQ, GTR, GEQ, LPARENT,
RPARENT, COMMA, SEMICOLON, PERIOD, BECOMES,
BEGINSYM, ENDSYM, IFSYM, THENSYM, WHILESYM,
DOSYM, CALLSYM, CONSTSYM, VARSYM, PROCSYM,
WRITESYM, READSYM
} Symbol;
/* 定义语法分析器的数据结构 */
typedef struct {
Symbol sym; /* 当前符号 */
int val; /* 当前数值 */
char id[10]; /* 当前标识符 */
FILE *fin; /* 输入文件指针 */
} Parser;
/* 初始化语法分析器 */
void init(Parser *parser, const char *filename) {
parser->fin = fopen(filename, "r");
if (!parser->fin) {
fprintf(stderr, "Cannot open file: %s\n", filename);
exit(1);
}
}
/* 从输入流中读取下一个符号 */
void nextSymbol(Parser *parser) {
// TODO: 实现读取下一个符号的代码
}
/* 抛出语法分析错误 */
void syntaxError(const char *msg) {
fprintf(stderr, "Syntax error: %s\n", msg);
exit(1);
}
/* 匹配指定的符号 */
void matchSymbol(Parser *parser, Symbol expected) {
if (parser->sym == expected) {
nextSymbol(parser);
} else {
char msg[100];
sprintf(msg, "Expected symbol: %d", expected);
syntaxError(msg);
}
}
/* 解析PL/0语言的程序 */
void parseProgram(Parser *parser) {
// TODO: 实现解析PL/0语言程序的代码
}
int main(int argc, char *argv[]) {
Parser parser;
if (argc < 2) {
fprintf(stderr, "Usage: %s filename\n", argv[0]);
return 1;
}
init(&parser, argv[1]);
nextSymbol(&parser);
parseProgram(&parser);
fclose(parser.fin);
return 0;
}
```
在上述代码中,我们定义了PL/0语言的词法分析器返回的符号类型`Symbol`,以及解析器的数据结构`Parser`。`init`函数用于初始化语法分析器,`nextSymbol`函数用于从输入流中读取下一个符号,`syntaxError`函数用于抛出语法分析错误,`matchSymbol`函数用于匹配指定的符号。`parseProgram`函数用于解析PL/0语言的程序。在`main`函数中,我们初始化语法分析器,读取第一个符号,然后调用`parseProgram`函数解析整个PL/0程序。
利用lex词法分析器生成工具,产生词法分析程序
步骤如下:
1. 编写词法规则文件,命名为lex文件,例如test.lex。其中包括定义需要识别的单词和符号的正则表达式,以及对应的处理代码。例如:
```
%{
#include <stdio.h>
#include <stdlib.h>
%}
%%
[0-9]+ { printf("NUM: %s\n", yytext); }
[a-zA-Z]+ { printf("ID: %s\n", yytext); }
[+\-*/] { printf("OP: %s\n", yytext); }
[ \t\n] { ; } // 空格、制表符和换行符忽略不计
. { printf("ERROR: %s\n", yytext); }
%%
int main(int argc, char* argv[]) {
if (argc != 2) {
fprintf(stderr, "Usage: %s filename\n", argv[0]);
exit(EXIT_FAILURE);
}
yyin = fopen(argv[1], "r");
if (yyin == NULL) {
fprintf(stderr, "Cannot open file %s\n", argv[1]);
exit(EXIT_FAILURE);
}
yylex();
fclose(yyin);
return 0;
}
```
2. 使用lex生成工具生成词法分析程序。在终端中执行以下命令:
```
lex test.lex
gcc lex.yy.c -o test
```
其中lex.yy.c是由lex生成的词法分析程序的源代码文件,test是生成的可执行文件。如果没有错误提示,则说明生成成功。
3. 运行生成的词法分析程序。在终端中执行以下命令:
```
./test input.txt
```
其中input.txt是待分析的源代码文件。程序会读取input.txt文件中的内容,对其中的单词和符号进行识别,输出对应的类型和值。如果有错误,则会输出ERROR信息。