词法分析器c语言编写
时间: 2023-07-02 16:12:01 浏览: 62
词法分析器 c语言编写
5星 · 资源好评率100%
词法分析器是编译器的一个重要组成部分,它的主要作用是将源代码中的字符序列转换成有意义的单词(Token),以供后续的语法分析和语义分析使用。下面是一个简单的词法分析器的 C 语言实现:
```c
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define MAX_TOKEN_LEN 100
enum TokenType {
KEYWORD, IDENTIFIER, NUMBER, STRING, OPERATOR, PUNCTUATOR
};
struct Token {
enum TokenType type;
char value[MAX_TOKEN_LEN];
};
int is_keyword(const char* token) {
static const char* keywords[] = {
"auto", "break", "case", "char", "const", "continue", "default", "do",
"double", "else", "enum", "extern", "float", "for", "goto", "if",
"int", "long", "register", "return", "short", "signed", "sizeof", "static",
"struct", "switch", "typedef", "union", "unsigned", "void", "volatile", "while"
};
static const int num_keywords = sizeof(keywords) / sizeof(keywords[0]);
for (int i = 0; i < num_keywords; ++i) {
if (strcmp(token, keywords[i]) == 0) {
return 1;
}
}
return 0;
}
int is_operator(char c) {
static const char* operators = "+-*/%=><&|!";
return strchr(operators, c) != NULL;
}
int is_punctuator(char c) {
static const char* punctuators = ",;()[]{}";
return strchr(punctuators, c) != NULL;
}
void get_token(char* input, struct Token* token) {
int len = strlen(input);
int i = 0;
while (i < len && isspace(input[i])) {
++i;
}
if (i == len) {
token->type = -1;
return;
}
if (isalpha(input[i])) {
int j = i + 1;
while (j < len && (isalnum(input[j]) || input[j] == '_')) {
++j;
}
strncpy(token->value, input + i, j - i);
token->value[j - i] = '\0';
if (is_keyword(token->value)) {
token->type = KEYWORD;
} else {
token->type = IDENTIFIER;
}
} else if (isdigit(input[i])) {
int j = i + 1;
while (j < len && isdigit(input[j])) {
++j;
}
strncpy(token->value, input + i, j - i);
token->value[j - i] = '\0';
token->type = NUMBER;
} else if (input[i] == '\"') {
int j = i + 1;
while (j < len && input[j] != '\"') {
++j;
}
strncpy(token->value, input + i + 1, j - i - 1);
token->value[j - i - 1] = '\0';
token->type = STRING;
} else if (is_operator(input[i])) {
if (input[i] == '/' && input[i + 1] == '/') {
token->type = -1;
return;
}
int j = i + 1;
if (input[i] == '>' || input[i] == '<' || input[i] == '&' || input[i] == '|') {
if (input[j] == input[i]) {
++j;
}
} else if (input[i] == '=') {
if (input[j] == '=') {
++j;
}
}
strncpy(token->value, input + i, j - i);
token->value[j - i] = '\0';
token->type = OPERATOR;
} else if (is_punctuator(input[i])) {
strncpy(token->value, input + i, 1);
token->value[1] = '\0';
token->type = PUNCTUATOR;
} else {
token->type = -1;
}
}
int main() {
char input[MAX_TOKEN_LEN];
struct Token token;
while (fgets(input, MAX_TOKEN_LEN, stdin)) {
get_token(input, &token);
if (token.type != -1) {
printf("%d %s\n", token.type, token.value);
}
}
return 0;
}
```
这里定义了五种 Token 类型:关键字、标识符、数字、字符串、运算符和标点符号。在 `get_token` 函数中,首先跳过输入字符串中的空白字符,然后根据第一个字符判断 Token 的类型。如果是字母,则继续扫描到非字母非数字非下划线字符为止,判断是否为关键字。如果是数字,则继续扫描到非数字字符为止。如果是双引号,则继续扫描到下一个双引号为止,将中间的字符作为字符串值。如果是运算符,则根据具体情况判断是否为多字符运算符。如果是标点符号,则直接将该字符作为 Token 值。对于注释,这里简单地忽略了。最后将 Token 的类型和值打印出来即可。
阅读全文