手把手带你写一门编程语言
宫文学
北京原点代码CEO
新⼈⾸单¥59.9
963 人已学习
课程目录
已更新 7 讲 / 共 38 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (2讲)
开篇词|让我们来写一门计算机语言吧
免费
课前热身|开始学习之前我们要准备什么?
起步篇:让一门超简单的语言跑起来 (5讲)
01|实现一门超简单的语言最快需要多久?
02|词法分析:识别Token也可以很简单吗?
03|支持表达式:解析表达式和解析语句有什么不同?
04|如何让我们的语言支持变量和类型?
05|函数实现:是时候让我们的语言支持函数和返回值了
手把手带你写一门编程语言
15
15
1.0x
00:00/00:00
登录|注册

04|如何让我们的语言支持变量和类型?

你好,我是宫文学。
到目前为止,我们的语言已经能够处理语句,也能够处理表达式,并且都能够解释执行了。不过,我们目前程序能够处理的数据,还都只是字面量而已。接下来,我们要增加一个重要的能力:支持变量
在程序中声明变量、对变量赋值、基于变量进行计算,是计算机语言的基本功能。只有支持了变量,我们才能实现那些更加强大的功能,比如,你可以用程序写一个计算物体下落的速度和位置,如何随时间变化的公式。这里的时间就是变量,通过给时间变量赋予不同的值,我们可以知道任意时间的物体速度和位置。
这一节,我就带你让我们手头上的语言能够支持变量。在这个过程中,你还会掌握语义分析的更多技能,比如类型处理等。
好了,我们已经知道了这一节的任务。那么第一步要做什么呢?你可以想到,我们首先要了解与处理变量声明和初始化有关的语法规则。

与变量有关的语法分析功能

在 TypeScript 中,我们在声明变量的时候,可以指定类型,这样有助于在编译期做类型检查:
let myAge : number = 18;
如果编译成 JavaScript,那么类型信息就会被抹掉:
var myAge = 18;
不过,因为我们的目标是教给你做类型分析的方法,以后还要静态编译成二进制的机器码,所以我们选择的是 TypeScript 的语法。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/1000字
划线
笔记
复制
该试读文章来自付费专栏《手把手带你写一门编程语言》,如需阅读全部文章,
请订阅文章所属专栏新⼈⾸单¥59.9
立即订阅
登录 后留言

精选留言(3)

  • _______R
    关于 typeAnnotation 的 follow 集合,根据文中的说法,冒号 ':' 是 First 集,那么 Follow 集就是各个类型关键字,这些关键字有:
    : booleaan 布尔值
    : number 数字
    : string 字符串
    : void
    : any
    : never
    : null
    : undefined
    : object 对象
    : Array<typeName> 数组
    : typeName[] 数组
    : [] 元组
    : identifier 自定义类型

    如果是 go 语言,则是
    i集合:int、int8、int16、int32、int64
    u集合:uint、uint8、uint16、uint32、uint64
    f集合:float32、float64
    c集合:complex64、complex128
    string 字符串
    bool 布尔值
    rune int32类型的别名,代表一个 UTF-8 字符
    byte uint8类型的别名,代表一个 ASCII 字符
    interface{} 空接口类型
    [n]typeName 数组类型
    []typeName slice 类型
    map[typeName]typeName map类型
    chan typeName channel 类型
    struct 结构体类型
    2021-08-17
  • leaf
    老师目前的语法规则我仔细看后觉得好像还不是很严谨
     * prog = statementList? EOF;
     * statementList = (variableDecl | functionDecl | expressionStatement)+ ;
     * variableDecl : 'let' Identifier typeAnnotation? ('=' singleExpression) ';';
     * typeAnnotation : ':' typeName;
     * functionDecl: "function" Identifier "(" ")" functionBody;
     * functionBody : '{' statementList? '}' ;
     * statement: functionDecl | expressionStatement;
     * expressionStatement: expression ';' ;
     * expression: primary (binOP primary)* ;
     * primary: StringLiteral | DecimalLiteral | IntegerLiteral | functionCall | '(' expression ')' ;
     * binOP: '+' | '-' | '*' | '/' | '=' | '+=' | '-=' | '*=' | '/=' | '==' | '!=' | '<=' | '>=' | '<'
     * | '>' | '&&'| '||'|...;
     * functionCall : Identifier '(' parameterList? ')' ;
     * parameterList : expression (',' expression)* ;
    例如variableDecl的最后一个括号是否应该带一个?, 且singleExpression未给出定义.
    还有定义了一条statement但并未在哪里用到阿.
    2021-08-17
  • leaf
    老师这节课的代码好像没有解决赋值语句的右结合问题吧, 比如对如下语句
        a = b = c;
    分析结果如下:
        ExpressionStatement
            Binary:=
                Binary:=
                    Variable: a, not resolved
                    Variable: b, not resolved
                Variable: c, not resolved
    这个结果还是左结合的阿
    2021-08-17
收起评论
3
返回
顶部