虽然这是一个常识性问题,但是我还是想知道为什么。
先来说明一下我们的这个语法解析工具,要解析的脚本很简单,只包括了&,|,~,=,!=,()和{}等操 作符。开始时采用了编译原理的那一套,画NFA、DFA,找出状态然后再写词法分析生成Token,接着语法分析将生成的Token根据语义生成语法树, 最后求值。后来想一想,这个脚本很简单只需要一个一个字符判断遇到不同类型的字符就进入到不同的子函数中进行处理,同时完成词法解析和语法分析以及求值的 过程。不过无论使用那种方法都需要根据读入的字符来判断当前进入到哪个Token里了,这就是问题的关键所在。为什么说判断字符属于哪个Token是关键呢?假设我们取消掉了变量名定义中不能以数字开头的限制,这时当词法分析器进入到一个Token分析的起始状态 时,如果读取的第一个字符为数字,那么词法分析器是无法判断它当前要分析的这个Token是变量名还是数字常量了。好,如果你说分析器可以根据后面的字符 来判断的话,那么如果下一个字符为字母,那么很容易就判断出当前Token属于变量名(我们暂且忽略保留关键字),但是当如果接下来的字符全都是数字那怎 么办?分析器将无法判断,因为变量名的定义中允许数字的存在。呵呵,上面也许说的比较绕口难于理解,用句简单的话来讲就是:当分析”123″这个字符串的时候,如果变量名允许第一个字符为数字,分析器就不知道“123”该是数值常量还是变量名了。总而言之,编译器在解析程序的时候,读到一个单词的第一个字符就需要知道当前这个单词属于那一类,这样方便于解析,不用回溯。
变量不能以数字开头,这是和我们所使用的编译器相关,也就是与编译原理有关。这应该算是词法分析的问题。因为每次输入“头符号”后要判断该符号是数字还是字符,如果是数字,则可以直接跳入数字处理的模块,若是字符则按变量名来处理。如果允许变量名以数字开头,则以后每次输入一个符号都要做一次“是否为数字”的判断,直到符号出现非数字再转成变量名,而禁止以数字开头只需要判断一次,很显然“每一次都要判断”是一种极大的浪费。当然有关介绍编译原理的书说的更清楚,你可以仔细研读下。
假如变量名允许以数字开头的话,那么语法分析器在解析一个全部为数字的字串的时候,就无法判断它是一个数字常量还是一个变量名了。
这个不一定,要看如何对源码进行处理,以前的LISP就允许变量名以数字开头。。。而如今大部分语言的编译器都是是使用CLR或者LALR方法进行语法分析的,所以说对于一些长整型数的定义就会产生歧义。。。
在C语言中,你可以定义这样的浮点数/长整型:
999f999l
在perl语言中,你可以定义这样的整数:
9_999_999
在python语言中,你可以定义这样的复数:
9+9j
如果,允许变量名首字母为数字,那么,就失去了上述的功能。
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
暂无简介
文章 0 评论 0
接受
发布评论
评论(5)
先来说明一下我们的这个语法解析工具,要解析的脚本很简单,只包括了&,|,~,=,!=,()和{}等操 作符。开始时采用了编译原理的那一套,画NFA、DFA,找出状态然后再写词法分析生成Token,接着语法分析将生成的Token根据语义生成语法树, 最后求值。后来想一想,这个脚本很简单只需要一个一个字符判断遇到不同类型的字符就进入到不同的子函数中进行处理,同时完成词法解析和语法分析以及求值的 过程。不过无论使用那种方法都需要根据读入的字符来判断当前进入到哪个Token里了,这就是问题的关键所在。
为什么说判断字符属于哪个Token是关键呢?假设我们取消掉了变量名定义中不能以数字开头的限制,这时当词法分析器进入到一个Token分析的起始状态 时,如果读取的第一个字符为数字,那么词法分析器是无法判断它当前要分析的这个Token是变量名还是数字常量了。好,如果你说分析器可以根据后面的字符 来判断的话,那么如果下一个字符为字母,那么很容易就判断出当前Token属于变量名(我们暂且忽略保留关键字),但是当如果接下来的字符全都是数字那怎 么办?分析器将无法判断,因为变量名的定义中允许数字的存在。
呵呵,上面也许说的比较绕口难于理解,用句简单的话来讲就是:当分析”123″这个字符串的时候,如果变量名允许第一个字符为数字,分析器就不知道“123”该是数值常量还是变量名了。
总而言之,编译器在解析程序的时候,读到一个单词的第一个字符就需要知道当前这个单词属于那一类,这样方便于解析,不用回溯。
变量不能以数字开头,这是和我们所使用的编译器相关,也就是与编译原理有关。这应该算是词法分析的问题。因为每次输入“头符号”后要判断该符号是数字还是字符,如果是数字,则可以直接跳入数字处理的模块,若是字符则按变量名来处理。如果允许变量名以数字开头,则以后每次输入一个符号都要做一次“是否为数字”的判断,直到符号出现非数字再转成变量名,而禁止以数字开头只需要判断一次,很显然“每一次都要判断”是一种极大的浪费。当然有关介绍编译原理的书说的更清楚,你可以仔细研读下。
假如变量名允许以数字开头的话,那么语法分析器在解析一个全部为数字的字串的时候,就无法判断它是一个数字常量还是一个变量名了。
这个不一定,要看如何对源码进行处理,以前的LISP就允许变量名以数字开头。。。
而如今大部分语言的编译器都是是使用CLR或者LALR方法进行语法分析的,所以说对于一些长整型数的定义就会产生歧义。。。
在C语言中,你可以定义这样的浮点数/长整型:
999f
999l
在perl语言中,你可以定义这样的整数:
9_999_999
在python语言中,你可以定义这样的复数:
9+9j
如果,允许变量名首字母为数字,那么,就失去了上述的功能。