解析器的输出是抽象语法树
对于数字字面量,创造了一个实例,并捕捉
变量捕捉函数名;二元表达式捕捉运算符;函数调用捕捉函数名和函数调用参数
函数原型和函数定义
构建语法树
getNextToken会从输入流里拿一个token,CurTok是这个token的token值
当我们的curtok是num的时候进这段解析,我们创建数字的对象,捕获值,然后拿下一个token,使curtok更新,并返回我们创建的数字量对象
括号运算符就是吃掉左括号,再次解析括号中间的表达式,最后返回来吃掉右括号,然后把中间构建好的对象返回
这里是解析变量和函数,当识别到是变量名的时候进这里解析,然后直接看下一个token,如果是不是括号,说明是变量名,直接返回变量对象;如果是括号,说明是函数调用。
综上我们有基本表达式的解析。
二元表达式解析
a+b+(c+d)*e*f+g
上来把左边用解析初级表达式解析一遍,
会解析出变量a,然后创建右树
进来的话当前字符是+,那么我们鉴定该运算符的优先级,是要大于0,对于左右树本身,运算符的优先级都要高,所以不进if
然后拿到当前的运算符之后,把符号移动到下一个,解析右树,这时候会返回b
然后再拿下一个运算符,这次是c前面的+,因为相等,所以不进if,所以创建出一个左边的树为a+b。
第二轮循环到c前面的+,也是到解析右树我们用初级表达式解析,这时候是有括号的
因为是(c+d),所以会进解析括号的表达式,这里就和我们一开始遇到a+b的情况一样,所以返回来的表达式是一个二元表达式树,这时候输入流是从c开始的字符流,当遇到)的时候,会返回所构建的左树对象,所以返回的是c+d的二元表达式对象结构。
回过来,下一个符号是*,这时候是要比c前面的+优先的,所以会进if,这时候逻辑是因为你后面有更有优先的运算,所以是没有构建完成这个表达式的,所以我们把此时的右树传进去,以他为左树开始构建,这时候这个部分的优先级就不是0了,而是+加1。
依照之前的逻辑我们很容易就能得到(c+d)*e*f的结构,那么能出来就是我们会遇到最后g之气那的+,这时候发现式子本身的优先级是比+大的,我们就从这里返回了。
也就是第二个循环结束的时候,我们已经把左树构造出来了
a+b+(c+d)*e*f
之后就是正常构造a+b+(c+d)*e*f+g,然后没有字符了,就会得到下一个符号的优先级是-1,,也从这个地方退出,返回整个指向这个树的指针
解析函数原型
首先拿函数名字,然后进括号里面拿函数的参数,一个个放进数组,直到遇到右括号,然后返回这个对象
解析函数定义
首先拿掉def,然后拿到函数原型,然后解析表达式,最后把原型和表达式(函数体)作为对象返回