欢迎光临散文网 会员登陆 & 注册

词法分析器-北太天元学习35

2023-08-13 00:19 作者:卢朓  | 我要投稿

编程语言是一种将文本(源代码)转换为行动的程序。因为编程语言是一个与其他程序协同工作的程序,所以听起来可能很复杂——甚至是不应该由普通人尝试的事情——但实际上,我们普通人也可以了解编程语言是如和工作的。

 

编程语言

编程语言把文本转化为行动,可以分成几个步骤,如下图所示:

编程语言工作的几个步骤

词法分析(lexical analysis)是计算机科学中将字符序列转换为单词(Token)序列的过程。进行词法分析的程序或者函数叫作词法分析器(Lexical analyzer,简称Lexer),也叫扫描器(Scanner)。词法分析器一般以函数的形式存在,供语法分析器调用。

我们下面给出一个用北太天元实现的词法解析器供大家参考:

我会给出一个视频,给大家简单介绍这个词法解析器,并且给出介绍北太天元的 global 关键字的使用方法,另外也会再次介绍 input 函数, fprintf 函数, strcmp 函数 的使用, 另外,也会介绍 switch 函数, 用惯了c/c++的朋友们,可能会在 switch 里使用defualt, 但是在北太天元里, 用otherwise 代替了default   c/c++的朋友用swtich 时还会经常用到 case 和 break,  但是在北太天元里每个case里相当于自动加了break,我会在视频里把这些区别讲一讲。

下面我也简单介绍一下这个词法解析器的功能, 对于输入一个字符串

'abc  if 1  x = 3  else  x =4  end #'

其中'#'时表示结束的字符,下面的词法分析器会把 abc , x 分类为变量, 把数字识别出来,

把 if else end 这些关键词识别出来。 在北太天元执行时的截图图下:

%北太天元 实现一个简单的词法分析器
clear all

global prog
global p
global token
global sum_
global rwtab
global syn

%prog = char(1,80); %这仅仅得到了一个2x1的char mat
prog = char(zeros(1,80)); % 这会得到一个80x1的char mat, 且初始化为''
token = char(zeros(1,8));
ch = '';
syn = 1;
p = 1;
m = 1;
n = 1;
row = 1;
sum_ = 0 ;
rwtab=["if","then","else", "switch","case","otherwise","end"];

fprintf("请输入一个单引号字符串, 以#结束\n");
while  1
    ch = input("");
    if(length(ch) > 0 )
       prog(p:p+length(ch)-1) = ch;
       p = p+length(ch);
    end
    if( length(ch) > 0 && strcmp(ch(end), '#') )
        break;
    end
end

 p=1;
 while 1
        scaner();
        switch  (syn)
        case 11  
            fprintf("(%d,%d)\n", syn, sum_);
        case -1  
                  fprintf("Error in row %d !\n",row);
        case -2
            row++;
        otherwise %相当于c/c++的default
             word  = string(token(find(token != '#')));
             if  (~isempty(word) && word ~= "")
                       fprintf("(%d,%s)\n", syn, word);
             end
    end
    if(syn == 0)
        break;
    end
end
 
function   scaner()
    global prog
    global p
    global token
    global sum_    
    global rwtab
    global syn
    /*
        共分为三大块,分别是token(关键字或者变量名)、数字、其它字符('>',':'等),
    */
    for n=1:8
    token(n)='#';
   end
    ch=prog(p++);
    while (ch==' ')
        ch=prog(p);
        p++;
    end

    if ((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))  %可能是关键字或者变量名
        m=1;
        while((ch>='0'&&ch<='9')||(ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))
            token(m++)=ch;
            ch=prog(p++);
    end
        token1 = token(1:m-1);
        p--;
        syn=10;
        for n=1:7  %将识别出来的字符和已定义的关键字作比较,
            if(strcmp(token1, rwtab(n) ))
                syn=n; %关键词的标志各不相同
                return;
        end
    end    
    elseif (ch>='0'&&ch<='9')  %数字
         sum_=0;
         while((ch>='0'&&ch<='9'))
              sum_=sum_*10+ch-'0';
              ch=prog(p++);
      end
        p--;
        syn=11;  %数字的标志是11
        if(sum_>32767)   
                  /*
                     如果数字大于32767, 则标志设置为-1,意味着出错
                     但是实际上有毛病,因为一个特别大的整数在这里会计算出
                     负数
                     */
            syn=-1;
    end    
    return;
    else
    switch(ch)   %其他字符
                case '<'
                    m = 1;
                    token(m++) = ch;
                    ch = prog(p++);
                    if( ch == '=')
                        syn = 22;
                        token(m++) = ch;
                    else
                        syn = 23;
                        p --;
                    end
                case '>'
                    m = 1;
                    token(m++) = ch;
                    ch = prog(p++);
                    if( ch == '=')
                        syn = 24;
                        token(m++) = ch;
                    else
                        syn = 20;
                        p --;
                    end
        case'*'
                    syn=13;token(1)=ch;
        case'/'
                    syn=14;token(1)=ch;
        case'+'
                    syn=15;token(1)=ch;
        case'-'
                    syn=16;token(1)=ch;
        case'='
                    syn=25;token(1)=ch;
        case';'
                    syn=26;token(1)=ch;
        case'('
                    syn=27;token(1)=ch;
        case')'
                    syn=28;token(1)=ch;
        case'#'
                    syn=0;token(1)=ch;
        case'\n'
                    syn=-2;
        default
                     syn=-1;
    end
   end
end



词法分析器-北太天元学习35的评论 (共 条)

分享到微博请遵守国家法律