用C语言实现一个词法分析器,要求识别输入的程序中所包含的单词符号,如关键字、标识符、常数、运算符等,输出单词符号及其对应的单词类型。
时间: 2024-11-15 10:20:10 浏览: 26
要实现一个简单的词法分析器(也称为扫描器或tokenizer),你需要设计一个函数来逐个读取输入字符并识别不同类型的符号。这里我们使用C语言来创建一个基础版本,主要关注关键字、标识符、数字和运算符的识别。请注意,这只是一个非常基础的例子,实际应用可能需要更复杂的正则表达式或状态机。
```c
#include <stdio.h>
#include <ctype.h>
// 定义词汇表中的关键字和运算符
#define KEYWORDS { "if", "else", "while", "for", ... }
#define OPERATORS { "=", "+", "-", "*", "/", "%", ...
typedef enum {
TOKEN_UNKNOWN,
TOKEN_IDENTIFIER,
TOKEN_NUMBER,
TOKEN_KEYWORD,
TOKEN_OPERATOR,
// 添加更多可能的令牌类型
} TokenType;
typedef struct {
char* text;
TokenType type;
} Token;
Token lexeme(const char* input, const char* keywords, const char* operators) {
Token token = { .text = NULL };
int in_number = 0; // 标记是否在处理数字
while (*input != '\0') {
if (isdigit(*input)) { // 数字
if (!in_number) {
token.text = malloc(3); // 预留三位空间
*token.text++ = '0'; // 开始添加数字
in_number = 1;
} else {
*token.text++ = *input++;
}
} else if (isalpha(*input) || *input == '_') { // 字母或下划线 - 标识符
*token.text++ = *input;
} else if (strchr(keywords, *input)) { // 关键字
token.type = TOKEN_KEYWORD;
break;
} else if (strchr(operators, *input)) { // 运算符
token.type = TOKEN_OPERATOR;
break;
} else { // 其他符号如空格、逗号等
if (token.text) {
*token.text = '\0';
return token;
}
input++;
}
input++;
}
// 如果结束位置还在字符串内,处理最后一个字符
if (in_number && token.text)
*token.text++ = '\0';
// 分配存储整个词的内存
token.text = realloc(token.text, strlen(token.text) + 1);
return token;
}
void print_token(Token token) {
switch (token.type) {
case TOKEN_UNKNOWN:
printf("Unknown symbol");
break;
case TOKEN_IDENTIFIER:
printf("Identifier: %s", token.text);
break;
case TOKEN_NUMBER:
printf("Number: %s", token.text);
break;
case TOKEN_KEYWORD:
printf("Keyword: %s", token.text);
break;
case TOKEN_OPERATOR:
printf("Operator: %s", token.text);
break;
default:
printf("Invalid token");
break;
}
printf("\n");
}
int main() {
const char* input = "if (x + y == 5) { printf('Hello World'); }";
const char* keywords = KEYWORDS;
const char* operators = OPERATORS;
while (*input) {
Token token = lexeme(input, keywords, operators);
print_token(token);
free(token.text);
}
return 0;
}
```
在这个例子中,`lexeme` 函数遍历输入字符串,根据字符类型分配给相应的词类型。然后在 `main` 函数中,我们对一个简单的示例程序进行分析,并打印每个识别到的词及其类型。
阅读全文