• 大小: 3KB
    文件类型: .rar
    金币: 2
    下载: 0 次
    发布日期: 2024-01-06
  • 语言: 其他
  • 标签: 计算器  

资源简介

词法分析器 -(计算器版)

资源截图

代码片段和文件信息

#include 
#include 
#include 
#include “token.h“

static char *st_line;
// 静态变量, 解析器记忆传入行 传入行的地址
static int st_line_pos;
//已经解析到的具体位置
//词法分析器是每传入一个字符就调用一次get_taken 那么 对于数字而言,一个数往往会包含多个数字,
typedef enum {
//这个枚举的作用是,将符合数值特征的指暂存起来
    INITIAL_STATUS
    IN_INT_PART_STATUS
    DOT_STATUS
    IN_FRAC_PART_STATUS
} LexerStatus;
//词法分析器的核心部分; 负责将记号实际分割
void
get_token(Token *token)
{
    int out_pos = 0;
    LexerStatus status = INITIAL_STATUS;//给status 设置初始值
    char current_char;

    token->kind = BAD_TOKEN;
    while (st_line[st_line_pos] != ‘\0‘) { //‘\0‘ 表示这行字符串的最后一个。
        current_char = st_line[st_line_pos];   //从0开始 第一个字符开始
        if ((status == IN_INT_PART_STATUS || status == IN_FRAC_PART_STATUS)
            //当前是属于整数 或  浮点数 的中间状态。
            && !isdigit(current_char) && current_char != ‘.‘) {
            //并且要同时满足当前  符号不是数字,不是 小数点
            token->kind = NUMBER_TOKEN;
            //把这个token 的类型确定为numbertoken
            sscanf(token->str “%lf“ &token->value);
            //从token的str 属性 中取出double 类型的值存到token->value
            //因为str中存的是字符串类型的值,而value 则是存的double 类型
            return;
        }
        if (isspace(current_char)) {   //如果当前这个是空格
            if (current_char == ‘\n‘) {  //如果是换行
                token->kind = END_OF_LINE_TOKEN;  //将token的kind 设置为end 类型,结束本token
                return;
            }
            st_line_pos++; //只是空格,不是换行,下标往前移动 //1.2   +1
            continue;  //继续执行while 循环体
        }

        if (out_pos >= MAX_TOKEN_SIZE-1) { //每个token 最多保存100个 字符。超过100 的话,退出程序
            fprintf(stderr “token too long.\n“);
            exit(1);
        }
        token->str[out_pos] = st_line[st_line_pos];//st_line_pos 行上下标,out_pos token 下标。
        st_line_pos++;
        out_pos++;
        token->str[out_pos] = ‘\0‘;  //koken->str 是一个字符数组,其最后一个必须保存‘\0‘
        //如果当前输入的字符为+ - * /  直接将taken 的kind 属性设置好,返回
        if (current_char == ‘+‘) {
            token->kind = ADD_OPERATOR_TOKEN;
            return;
        } else if (current_char == ‘-‘) {
            token->kind = SUB_OPERATOR_TOKEN;
            return;
        } else if (current_char == ‘*‘) {
            token->kind = MUL_OPERATOR_TOKEN;
            return;
        } else if (current_char == ‘/‘) {
            token->kind = DIV_OPERATOR_TOKEN;
            return;
        } else if (isdigit(current_char)) {
            if (status == INITIAL_STATUS) {
                status = IN_INT_PART_STATUS;  //进入的是0-9 ,则会将状态修改为int 类型
            } else if (status == DOT_STATUS) {
                status = IN_FRAC_PART_STATUS;  //点之后遇到数字 状态改为小数
            }
        } else if (current_char == ‘.‘) {
            if (status == IN_INT_PART_STATUS) {
                status = DOT_STATUS; //进入的是小数点 ,则会将状态修改为dot  类型
            } else {
                fprintf(stderr “syntax error.\n“);
                exit(1);
            }
        } else {
            fprintf(stderr

 属性            大小     日期    时间   名称
----------- ---------  ---------- -----  ----

     文件       4928  2017-03-15 16:31  lexicalanalyzer.c

     文件       2374  2008-12-19 07:38  parser.c

     文件        498  2017-03-15 16:35  token.h

----------- ---------  ---------- -----  ----

                 7800                    3


评论

共有 条评论