编译原理 第二章 词法分析器 练习2.6

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace Compiler
{
    class Reader
    {
        private string str;
        private int lookahead;
        private StreamReader fs;
        private bool readfromfile = false;
        private bool eof = false;
        public Reader(string input)
        {
            str = new string(input);
            lookahead = 0;
            readfromfile = false;
        }
        public Reader() { }
        public void openFile(string path)
        {
            fs = new StreamReader(path);
            readfromfile = true;
            eof = false;
        }


        public char next()
        {
            if (!readfromfile)
            {
                try
                {
                    return str[lookahead++];
                }
                catch (Exception)
                {
                    if (lookahead <= str.Length + 1)
                    {
                        return ' ';
                    }
                    else
                    {
                        throw new Exception("End of File");
                    }
                }
            }
            else
            {
                if (fs.Peek() >= 0)
                {
                    return (char)fs.Read();
                }
                else
                {
                    if (eof) throw new Exception("End of File");
                    eof = true;
                    return ' ';
                }

            }
        }

    }
}
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;

namespace Compiler
{
    class Lexer
    {
        private Reader reader;
        private char peek;
        public int line;
        private Hashtable words;
        private void increasePeek() => peek = reader.next();
        private void increPeekToUseful()
        {
            for (; ; increasePeek())
            {
                if (peek == ' ' || peek == '\t')
                {
                    continue;
                }
                if (peek == '\n' || peek == '\r')
                {
                    line++;
                    continue;
                }
                else break;
            }
        }
        /// <summary>
        /// 处理运算符,可能为多元运算符或注释
        /// 当处理注释时,返回null,peek为' '
        /// 当处理运算符时,返回运算符,peek为下一个词素
        /// </summary>
        private Token? handleSigns()
        {
            char pre = peek;
            increasePeek();
            switch (pre)
            {
                case '/':
                    if (peek == '/')
                    {
                        while (peek != '\n')
                        {
                            increasePeek();
                        }
                        return null;
                    }
                    else if (peek == '*')
                    {
                        increasePeek();
                        do
                        {
                            pre = peek;
                            increasePeek();
                        }
                        while (pre != '*' || peek != '/');
                        peek = ' ';
                        return null;
                    }
                    else
                    {
                        return new Token(pre);
                    }
                case '<':
                    if (peek == '=')
                    {
                        peek = ' ';
                        return new Token(Tag.LESS_OR_EQUAL);
                    }
                    else return new Token('<');
                case '=':
                    if (peek == '=')
                    {
                        peek = ' ';
                        return new Token(Tag.EQUAL);
                    }
                    else return new Token('=');
                case '!':
                    if (peek == '=')
                    {
                        peek = ' ';
                        return new Token(Tag.NOT_EQUAL);
                    }
                    else return new Token('!');
                case '>':
                    if (peek == '=')
                    {
                        peek = ' ';
                        return new Token(Tag.GREATER_OR_EQUAL);
                    }
                    else return new Token('>');
                default:
                    return new Token(pre);
            }
            
        }
        private Token handleDigit()
        {
            int v = 0;
            while (char.IsDigit(peek))
            {
                v = v * 10 + peek - '0';
                increasePeek();
            }
            if (peek == '.')
            {
                double f = v;
                double mut = 1;
                increasePeek();
                while (char.IsDigit(peek))
                {
                    mut /= 10;
                    f += mut * (peek - '0');
                    increasePeek();
                }
                return new Float(f);
            }
            return new Num(v);
        }
        private Word handleLetter()
        {
            StringBuilder buffer = new StringBuilder();
            do
            {
                buffer.Append(peek);
                increasePeek();
            } while (char.IsLetterOrDigit(peek));
            string str = buffer.ToString();
            if (words.ContainsKey(str))
            {
                return new Word((Tag)words[str], str);
            }
            Word w = new Word(Tag.ID, str);
            words.Add(w.lexeme, w.tag);
            return w;
        }
        private void reserve(Word t) => words.Add(t.lexeme, t.tag);
        public Lexer(Reader _reader)
        {
            reader = _reader;
            peek = ' ';
            line = 1;
            words = new Hashtable();

            reserve(new Word(Tag.TRUE, "true"));
            reserve(new Word(Tag.FALSE, "false"));
        }
        /// <summary>
        /// 结束时抛出异常
        /// </summary>
        /// <returns></returns>
        public Token scan()
        {
            while (true)
            {
                increPeekToUseful();
                if (char.IsDigit(peek) || peek == '.')
                {
                    return handleDigit();
                }
                if (char.IsLetter(peek))
                {
                    return handleLetter();
                }
                Token t = handleSigns();
                if (t != null) return t;
            }
        }

    }
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
第1章 引论  1.1 翻译程序  1.2 为什么需要编译程序  1.3 编译程序的工作过程  1.4 编译程序的结构  1.5 编译程序的组织方式  1.6 编译程序的其他有关技术  1.7 翻译程序编写系统  1.8 并行编译程序  1.9 小结  习题一 第2章 形式语言概论  2.1 语言成分  2.2 产生式文法和语言  2.3 文法的分类  2.4 语言和语法  2.5 文法和语言的一些特性  2.6 分析方法简介  2.7 小结  习题二 第3章有穷自动机  3.1 概述  3.2 有穷自动机的形式定义  3.3 NDFSA到DFSA的转换  3.4 正规文法和有穷自动机  3.5 正规表达式与FSA  3.6 DFSA在计算机中的表示  3.7 小结  习题三 第4章词法分析  4.1 词法分析概述  4.2 单词符号  4.3 扫描程序的设计  4.4 标识符的处理  4.5 设计词法分析程序的直接方法  4.6 与设计扫描程序相关的几个问题  4.7 小结  习题四 第5章 自上而下语法分析  5.1 非确定的下推自动机  5.2 消除左递归方法  5.3 LL(k)文法  5.4 确定的LL(1)分析器的构造  5.5 LL(k)文法的几个结论  5.6 递归下降分析程序及其设计  5.7 带回溯的自上而下分析法  5.8 小结   习题五 第6章 自下而上分析和优先分析方法  6.1 短语和句柄  6.2 移进-归约方法  6.3 非确定的自下而上分析器  6.4 有关文法的一些关系  6.5 简单优先分析方法  6.6 算符优先分析方法  6.7 优先函数及其构造  6.8 两种优先分析方法的比较  6.9 小结   习题六 第7章 自下而上的LR(k)分析方法  7.1 LR(k)文法和LR(k)分析器  7.2 LR(0)分析表的构造  7.3 SLR分析表的构造  7.4 规范LR(1)分析表的构造  7.5 LALR分析表的构造  7.6 无二义性规则的使用  7.7 小结  习题七 第8章 语法制导翻译法  8.1 一般原理和树变换  8.2 简单SDTS和自上而下翻译器  8.3 简单后缀SDTS和自下而上翻译器  8.4 抽象语法树的构造  8.5 属性文法  8.6 中间代码形式  8.7 属性翻译文法的应用  8.8 小结  习题八 第9章 运行时的存储组织与管理  9.1 数据区和属性字  9.2 基本数据类型的存储分配  9.3 数组的存储分配  9.4 记录结构的存储分配  9.5 参数传递方式及其实现  9.6 栈式存储分配方法  9.7 堆式存储分配方法  9.8 临时工作单元的存储分配  9.9 小结  习题九 第10章 符号表的组织和查找  10.1 符号表的一般组织形式  10.2 符号表中的数据  10.3 符号表的构造与查找  10.4 分程序结构的符号表  10.5 小结  习题十 第11章 优化  11.1 基本块及其求法  11.2 优化举例  11.3 利用变量的定义点进行优化  11.4 循环优化  11.5 借助DAG进行优化  11.6 并行分支的优化  11.7 窥孔优化  11.8 小结  习题十一 第12章 代码生成  12.1 假想的计算机模型  12.2 从四元式生成代码  12.3 从三元式生成代码  12.4 从树形表示生成代码  12.5 从逆波兰表示生成代码  12.6 寄存器的分配  12.7 小结  习题十二 第13章 词法分析器生成工具LEX 第14章 语法分析器生成工具YACC 参考文献
目录 第一章简介 问题与答案 这本书适合你吗? 为何有这么多的脚注? 关于习题和解答? 习题前标的数字是什么意思? 如果我是Perl讲师? “Perl”这个词表示什么意思? Larry为什么要创造Perl? Larry干吗不用其他语言? Perl算容易,还是算难? Perl怎么会这么流行? 现在的Perl发展得怎么样了? 哪些事情最适合用Perl来做? 哪些事情不适合用Perl来做? 如何取得Perl? CPAN是什么? 如何得到Perl的技术支持? 还有别的技术支持方式吗? 如果发现Perl有bug,我该怎么办? 我该怎么编写Perl程序? 一个简单的程序 程序里写的是什么? 我该如何编译Perl程序? 走马观花 习题 第二章标量数据 数字 所有数字的内部格式都相同 浮点数直接量 整数直接量 非+进制整数的直接量 数字操作符 字符串 单引号内的字符串直接量 双引号内的字符串直接量 字符串操作符 数字与字符串之间的自动转换 Perl的内置警告信息 标量变量 给变量取个好名字 标量的赋值 双目赋值操作符 用print输出结果 字符串中的标量变量内插 借助代码点创建字符 操作符的优先级与结合性 比较操作符 if控制结构 布尔值 获取用户输入 chomp操作符 while控制结构 undef值 defined函数 习题 第三章列表与数组 访问数组中的元素 特殊的数组索引 列表直接量 qw简写 列表的赋值 pop和push操作符 shift和unshift操作符 splice操作符 字符串中的数组内插 foreach控制结构 Perl最喜欢用的默认变量:$_ reverse操作符 sort操作符 each操作符 标量上下文与列表上下文 在标量上下文中使用产生列表的表达式 在列表上下文中使用产生标量的表达式 强制指定标量上下文 列表上下文中的 习题 第四章子程序 定义子程序 调用子程序 返回值 参数 子程序中的私有变量 变长参数列表 改进的&max子程序 空参数列表 关于词法(my)变量 use strict编译指令 return操作符 省略与号 非标量返回值 持久化私有变量 习题 第五章输入与输出 读取标准输入 来自钻石操作符的输入 调用参数 输出到标准输出 JNprintf格式化输出 数组和printf 文件句柄 打开文件句柄 以二进制方式读写文件句柄 有问题的文件句柄 关闭文件句柄 用die处理致命错误 用warn输出警告信息 自动检测致命错误 使用文件句柄 改变默认的文件输出句柄 重新打开标准文件句柄 用say来输出 …… 第六章哈希 第七章漫游正则表达式王国 第八章用正则表达式进行匹配 第九章用正则表达式处理文本 第十章其他控制结构 第十一章Perl模块 第十二章文件测试 第十三章目录操作 第十四章字符串与排序 第十五章智能匹配与given—when结构 第十六章进程管理 第十七章高级Perl技巧 附录

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值