Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Compilers 101: An introduction to programming languages and parsing

Compilers 101: An introduction to programming languages and parsing

I gave this talk at Coderfaire, August 17, 2013. As usual, the slides do not make a ton of sense without the words. Sorry!

However they contain a complete recursive-descent parser for a toy grammar, in JS. I’ve never given a talk with this much code before. The slides reveal this code line by line, and that worked out very nicely.

More resources for this talk: http://gist.io/6256943

Jason Orendorff

August 17, 2013
Tweet

More Decks by Jason Orendorff

Other Decks in Programming

Transcript

  1. 17 August 2013
    Compilers 101
    An introduction to programming languages and parsing
    Tuesday, September 3, 13

    View Slide

  2. 17 August 2013
    Compilers 101
    An introduction to programming languages and parsing
    WARNING
    CONTAINS CODE
    0
    0
    0
    1
    1
    Tuesday, September 3, 13

    View Slide

  3. gist.io/6256943
    Tuesday, September 3, 13

    View Slide

  4. Tuesday, September 3, 13

    View Slide

  5. Tuesday, September 3, 13

    View Slide

  6. green big ball
    Tuesday, September 3, 13

    View Slide

  7. green big ball
    big green ball
    Tuesday, September 3, 13

    View Slide

  8. Tuesday, September 3, 13

    View Slide

  9. A compiler is
    Tuesday, September 3, 13

    View Slide

  10. A compiler is a program that translates code
    Tuesday, September 3, 13

    View Slide

  11. A compiler is a program that translates code
    from one language to another.
    Tuesday, September 3, 13

    View Slide

  12. A compiler is a program that translates code
    from one language to another.
    ✤ to machine code (like FORTRAN, C, Go)
    Tuesday, September 3, 13

    View Slide

  13. A compiler is a program that translates code
    from one language to another.
    ✤ to machine code (like FORTRAN, C, Go)
    ✤ to bytecode (like Java, Python)
    Tuesday, September 3, 13

    View Slide

  14. A compiler is a program that translates code
    from one language to another.
    ✤ to machine code (like FORTRAN, C, Go)
    ✤ to bytecode (like Java, Python)
    ✤ to another high-level language (cfront,
    LESS & Sass, CoffeeScript, Traceur,
    emscripten)
    Tuesday, September 3, 13

    View Slide

  15. Tuesday, September 3, 13

    View Slide

  16. Language is a different kind of data.
    Tuesday, September 3, 13

    View Slide

  17. Language is a different kind of data.
    It’s not line-based.
    Tuesday, September 3, 13

    View Slide

  18. Language is a different kind of data.
    It’s not line-based.
    It’s not record-based.
    Tuesday, September 3, 13

    View Slide

  19. Language is a different kind of data.
    It’s not line-based.
    It’s not record-based.
    And you can’t fake understanding.
    Tuesday, September 3, 13

    View Slide

  20. Language is a different kind of data.
    It’s not line-based.
    It’s not record-based.
    And you can’t fake understanding.
    Language has structure.
    Tuesday, September 3, 13

    View Slide

  21. Tuesday, September 3, 13

    View Slide

  22. when flag clicked
    forever
    point towards mouse-pointer
    if
    move 3 * speed steps
    not touching mouse-pointer ? then
    Tuesday, September 3, 13

    View Slide

  23. when flag clicked
    forever
    point towards mouse-pointer
    if
    move 3 * speed steps
    not touching mouse-pointer ? then
    Tuesday, September 3, 13

    View Slide

  24. Inside a compiler
    Tuesday, September 3, 13

    View Slide

  25. Inside a compiler
    Tuesday, September 3, 13

    View Slide

  26. front end
    (parsing, analysis)
    Inside a compiler
    Tuesday, September 3, 13

    View Slide

  27. front end
    (parsing, analysis)
    Inside a compiler
    Tuesday, September 3, 13

    View Slide

  28. front end
    (parsing, analysis)
    back end
    (code generation)
    Inside a compiler
    Tuesday, September 3, 13

    View Slide

  29. front end
    (parsing, analysis)
    back end
    (code generation)
    Inside a compiler
    Tuesday, September 3, 13

    View Slide

  30. front end
    (parsing, analysis)
    back end
    (code generation)
    sleep(2*x)
    Inside a compiler
    Tuesday, September 3, 13

    View Slide

  31. front end
    (parsing, analysis)
    back end
    (code generation)
    sleep(2*x)
    pushq %rbp
    movq %rsp, %rbp
    addl %edi, %edi
    callq _sleep
    Inside a compiler
    Tuesday, September 3, 13

    View Slide

  32. front end
    (parsing, analysis)
    back end
    (code generation)
    sleep(2*x)
    call
    sleep *
    2 x
    pushq %rbp
    movq %rsp, %rbp
    addl %edi, %edi
    callq _sleep
    Inside a compiler
    Tuesday, September 3, 13

    View Slide

  33. Inside a front end
    Tuesday, September 3, 13

    View Slide

  34. Inside a front end
    tokenizer
    Tuesday, September 3, 13

    View Slide

  35. Inside a front end
    tokenizer parser
    Tuesday, September 3, 13

    View Slide

  36. Inside a front end
    tokenizer parser AST builder
    Tuesday, September 3, 13

    View Slide

  37. Inside a front end
    tokenizer parser AST builder
    12*x
    Tuesday, September 3, 13

    View Slide

  38. Inside a front end
    tokenizer parser AST builder
    12*x *
    12 x
    Tuesday, September 3, 13

    View Slide

  39. Inside a front end
    tokenizer parser AST builder
    12*x *
    12 x
    ['12', '*', 'x']
    Tuesday, September 3, 13

    View Slide

  40. Inside a front end
    tokenizer parser AST builder
    12*x *
    12 x
    ['12', '*', 'x']
    Tuesday, September 3, 13

    View Slide

  41. Inside a front end
    tokenizer parser AST builder
    12*x *
    12 x
    ['12', '*', 'x']
    out.number('12')
    Tuesday, September 3, 13

    View Slide

  42. Inside a front end
    tokenizer parser AST builder
    12*x *
    12 x
    ['12', '*', 'x']
    out.number('12')
    out.name('x')
    Tuesday, September 3, 13

    View Slide

  43. Inside a front end
    tokenizer parser AST builder
    12*x *
    12 x
    ['12', '*', 'x']
    out.number('12')
    out.name('x')
    out.mul(
    ,
    )
    Tuesday, September 3, 13

    View Slide

  44. IfStatement :
    if ( Expression ) Statement else Statement
    if ( Expression ) Statement
    Tuesday, September 3, 13

    View Slide

  45. Statement :
    Block
    VariableStatement
    EmptyStatement
    ExpressionStatement
    IfStatement
    IterationStatement
    ContinueStatement
    BreakStatement
    ReturnStatement
    WithStatement
    LabelledStatement
    Tuesday, September 3, 13

    View Slide

  46. Tuesday, September 3, 13

    View Slide

  47. PrimaryExpr :
    Number
    Name
    ( Expr )
    MulExpr :
    PrimaryExpr ( * PrimaryExpr | / PrimaryExpr )*
    Expr :
    MulExpr ( + MulExpr | - MulExpr )*
    Tuesday, September 3, 13

    View Slide

  48. PrimaryExpr :
    Number
    Name
    ( Expr )
    MulExpr :
    PrimaryExpr ( * PrimaryExpr | / PrimaryExpr )*
    Expr :
    MulExpr ( + MulExpr | - MulExpr )*
    out.number("3")
    Tuesday, September 3, 13

    View Slide

  49. PrimaryExpr :
    Number
    Name
    ( Expr )
    MulExpr :
    PrimaryExpr ( * PrimaryExpr | / PrimaryExpr )*
    Expr :
    MulExpr ( + MulExpr | - MulExpr )*
    out.number("3")
    out.name("pi")
    Tuesday, September 3, 13

    View Slide

  50. PrimaryExpr :
    Number
    Name
    ( Expr )
    MulExpr :
    PrimaryExpr ( * PrimaryExpr | / PrimaryExpr )*
    Expr :
    MulExpr ( + MulExpr | - MulExpr )*
    out.number("3")
    out.name("pi")
    out.mul(lhs, rhs)
    Tuesday, September 3, 13

    View Slide

  51. PrimaryExpr :
    Number
    Name
    ( Expr )
    MulExpr :
    PrimaryExpr ( * PrimaryExpr | / PrimaryExpr )*
    Expr :
    MulExpr ( + MulExpr | - MulExpr )*
    out.number("3")
    out.name("pi")
    out.mul(lhs, rhs)
    out.add(lhs, rhs)
    Tuesday, September 3, 13

    View Slide

  52. function parse(code, out) {
    var tokens = tokenize(code);
    var position = 0;
    function peek() {
    return tokens[position];
    }
    function consume(token) {
    assert.strictEqual(token, tokens[position]);
    position++;
    }
    Calculator parser - page 1 of 5
    Tuesday, September 3, 13

    View Slide

  53. function parse(code, out) {
    var tokens = tokenize(code);
    var position = 0;
    function peek() {
    return tokens[position];
    }
    function consume(token) {
    assert.strictEqual(token, tokens[position]);
    position++;
    }
    Calculator parser - page 1 of 5
    Tuesday, September 3, 13

    View Slide

  54. function parse(code, out) {
    var tokens = tokenize(code);
    var position = 0;
    function peek() {
    return tokens[position];
    }
    function consume(token) {
    assert.strictEqual(token, tokens[position]);
    position++;
    }
    Calculator parser - page 1 of 5
    Tuesday, September 3, 13

    View Slide

  55. function parse(code, out) {
    var tokens = tokenize(code);
    var position = 0;
    function peek() {
    return tokens[position];
    }
    function consume(token) {
    assert.strictEqual(token, tokens[position]);
    position++;
    }
    Calculator parser - page 1 of 5
    Tuesday, September 3, 13

    View Slide

  56. function parse(code, out) {
    var tokens = tokenize(code);
    var position = 0;
    function peek() {
    return tokens[position];
    }
    function consume(token) {
    assert.strictEqual(token, tokens[position]);
    position++;
    }
    Calculator parser - page 1 of 5
    Tuesday, September 3, 13

    View Slide

  57. function parse(code, out) {
    var tokens = tokenize(code);
    var position = 0;
    function peek() {
    return tokens[position];
    }
    function consume(token) {
    assert.strictEqual(token, tokens[position]);
    position++;
    }
    Calculator parser - page 1 of 5
    Tuesday, September 3, 13

    View Slide

  58. function parse(code, out) {
    var tokens = tokenize(code);
    var position = 0;
    function peek() {
    return tokens[position];
    }
    function consume(token) {
    assert.strictEqual(token, tokens[position]);
    position++;
    }
    Calculator parser - page 1 of 5
    Tuesday, September 3, 13

    View Slide

  59. function parsePrimaryExpr() {
    var t = peek();
    if (isNumber(t)) {
    consume(t);
    return out.number(t);
    } else if (isName(t)) {
    consume(t);
    return out.name(t);
    } else if (t === "(") {
    consume(t);
    var expr = parseExpr();
    if (peek() !== ")")
    throw new SyntaxError("expected )");
    consume(")");
    return expr;
    } else {
    throw new SyntaxError("didn't expect '" + t + "'");
    }
    }
    Calculator parser - page 2 of 5 PrimaryExpr :
    Number
    Name
    ( Expr )
    Tuesday, September 3, 13

    View Slide

  60. function parsePrimaryExpr() {
    var t = peek();
    if (isNumber(t)) {
    consume(t);
    return out.number(t);
    } else if (isName(t)) {
    consume(t);
    return out.name(t);
    } else if (t === "(") {
    consume(t);
    var expr = parseExpr();
    if (peek() !== ")")
    throw new SyntaxError("expected )");
    consume(")");
    return expr;
    } else {
    throw new SyntaxError("didn't expect '" + t + "'");
    }
    }
    Calculator parser - page 2 of 5 PrimaryExpr :
    Number
    Name
    ( Expr )
    Tuesday, September 3, 13

    View Slide

  61. function parsePrimaryExpr() {
    var t = peek();
    if (isNumber(t)) {
    consume(t);
    return out.number(t);
    } else if (isName(t)) {
    consume(t);
    return out.name(t);
    } else if (t === "(") {
    consume(t);
    var expr = parseExpr();
    if (peek() !== ")")
    throw new SyntaxError("expected )");
    consume(")");
    return expr;
    } else {
    throw new SyntaxError("didn't expect '" + t + "'");
    }
    }
    Calculator parser - page 2 of 5 PrimaryExpr :
    Number
    Name
    ( Expr )
    Tuesday, September 3, 13

    View Slide

  62. function parsePrimaryExpr() {
    var t = peek();
    if (isNumber(t)) {
    consume(t);
    return out.number(t);
    } else if (isName(t)) {
    consume(t);
    return out.name(t);
    } else if (t === "(") {
    consume(t);
    var expr = parseExpr();
    if (peek() !== ")")
    throw new SyntaxError("expected )");
    consume(")");
    return expr;
    } else {
    throw new SyntaxError("didn't expect '" + t + "'");
    }
    }
    Calculator parser - page 2 of 5 PrimaryExpr :
    Number
    Name
    ( Expr )
    Tuesday, September 3, 13

    View Slide

  63. function parsePrimaryExpr() {
    var t = peek();
    if (isNumber(t)) {
    consume(t);
    return out.number(t);
    } else if (isName(t)) {
    consume(t);
    return out.name(t);
    } else if (t === "(") {
    consume(t);
    var expr = parseExpr();
    if (peek() !== ")")
    throw new SyntaxError("expected )");
    consume(")");
    return expr;
    } else {
    throw new SyntaxError("didn't expect '" + t + "'");
    }
    }
    Calculator parser - page 2 of 5 PrimaryExpr :
    Number
    Name
    ( Expr )
    Tuesday, September 3, 13

    View Slide

  64. function parsePrimaryExpr() {
    var t = peek();
    if (isNumber(t)) {
    consume(t);
    return out.number(t);
    } else if (isName(t)) {
    consume(t);
    return out.name(t);
    } else if (t === "(") {
    consume(t);
    var expr = parseExpr();
    if (peek() !== ")")
    throw new SyntaxError("expected )");
    consume(")");
    return expr;
    } else {
    throw new SyntaxError("didn't expect '" + t + "'");
    }
    }
    Calculator parser - page 2 of 5 PrimaryExpr :
    Number
    Name
    ( Expr )
    Tuesday, September 3, 13

    View Slide

  65. function parsePrimaryExpr() {
    var t = peek();
    if (isNumber(t)) {
    consume(t);
    return out.number(t);
    } else if (isName(t)) {
    consume(t);
    return out.name(t);
    } else if (t === "(") {
    consume(t);
    var expr = parseExpr();
    if (peek() !== ")")
    throw new SyntaxError("expected )");
    consume(")");
    return expr;
    } else {
    throw new SyntaxError("didn't expect '" + t + "'");
    }
    }
    Calculator parser - page 2 of 5 PrimaryExpr :
    Number
    Name
    ( Expr )
    Tuesday, September 3, 13

    View Slide

  66. function parsePrimaryExpr() {
    var t = peek();
    if (isNumber(t)) {
    consume(t);
    return out.number(t);
    } else if (isName(t)) {
    consume(t);
    return out.name(t);
    } else if (t === "(") {
    consume(t);
    var expr = parseExpr();
    if (peek() !== ")")
    throw new SyntaxError("expected )");
    consume(")");
    return expr;
    } else {
    throw new SyntaxError("didn't expect '" + t + "'");
    }
    }
    Calculator parser - page 2 of 5 PrimaryExpr :
    Number
    Name
    ( Expr )
    Tuesday, September 3, 13

    View Slide

  67. function parsePrimaryExpr() {
    var t = peek();
    if (isNumber(t)) {
    consume(t);
    return out.number(t);
    } else if (isName(t)) {
    consume(t);
    return out.name(t);
    } else if (t === "(") {
    consume(t);
    var expr = parseExpr();
    if (peek() !== ")")
    throw new SyntaxError("expected )");
    consume(")");
    return expr;
    } else {
    throw new SyntaxError("didn't expect '" + t + "'");
    }
    }
    Calculator parser - page 2 of 5 PrimaryExpr :
    Number
    Name
    ( Expr )
    Tuesday, September 3, 13

    View Slide

  68. function parsePrimaryExpr() {
    var t = peek();
    if (isNumber(t)) {
    consume(t);
    return out.number(t);
    } else if (isName(t)) {
    consume(t);
    return out.name(t);
    } else if (t === "(") {
    consume(t);
    var expr = parseExpr();
    if (peek() !== ")")
    throw new SyntaxError("expected )");
    consume(")");
    return expr;
    } else {
    throw new SyntaxError("didn't expect '" + t + "'");
    }
    }
    Calculator parser - page 2 of 5 PrimaryExpr :
    Number
    Name
    ( Expr )
    Tuesday, September 3, 13

    View Slide

  69. function parsePrimaryExpr() {
    var t = peek();
    if (isNumber(t)) {
    consume(t);
    return out.number(t);
    } else if (isName(t)) {
    consume(t);
    return out.name(t);
    } else if (t === "(") {
    consume(t);
    var expr = parseExpr();
    if (peek() !== ")")
    throw new SyntaxError("expected )");
    consume(")");
    return expr;
    } else {
    throw new SyntaxError("didn't expect '" + t + "'");
    }
    }
    Calculator parser - page 2 of 5 PrimaryExpr :
    Number
    Name
    ( Expr )
    Tuesday, September 3, 13

    View Slide

  70. function parsePrimaryExpr() {
    var t = peek();
    if (isNumber(t)) {
    consume(t);
    return out.number(t);
    } else if (isName(t)) {
    consume(t);
    return out.name(t);
    } else if (t === "(") {
    consume(t);
    var expr = parseExpr();
    if (peek() !== ")")
    throw new SyntaxError("expected )");
    consume(")");
    return expr;
    } else {
    throw new SyntaxError("didn't expect '" + t + "'");
    }
    }
    Calculator parser - page 2 of 5 PrimaryExpr :
    Number
    Name
    ( Expr )
    Tuesday, September 3, 13

    View Slide

  71. function parsePrimaryExpr() {
    var t = peek();
    if (isNumber(t)) {
    consume(t);
    return out.number(t);
    } else if (isName(t)) {
    consume(t);
    return out.name(t);
    } else if (t === "(") {
    consume(t);
    var expr = parseExpr();
    if (peek() !== ")")
    throw new SyntaxError("expected )");
    consume(")");
    return expr;
    } else {
    throw new SyntaxError("didn't expect '" + t + "'");
    }
    }
    Calculator parser - page 2 of 5 PrimaryExpr :
    Number
    Name
    ( Expr )
    Tuesday, September 3, 13

    View Slide

  72. function parsePrimaryExpr() {
    var t = peek();
    if (isNumber(t)) {
    consume(t);
    return out.number(t);
    } else if (isName(t)) {
    consume(t);
    return out.name(t);
    } else if (t === "(") {
    consume(t);
    var expr = parseExpr();
    if (peek() !== ")")
    throw new SyntaxError("expected )");
    consume(")");
    return expr;
    } else {
    throw new SyntaxError("didn't expect '" + t + "'");
    }
    }
    Calculator parser - page 2 of 5 PrimaryExpr :
    Number
    Name
    ( Expr )
    Tuesday, September 3, 13

    View Slide

  73. function parsePrimaryExpr() {
    var t = peek();
    if (isNumber(t)) {
    consume(t);
    return out.number(t);
    } else if (isName(t)) {
    consume(t);
    return out.name(t);
    } else if (t === "(") {
    consume(t);
    var expr = parseExpr();
    if (peek() !== ")")
    throw new SyntaxError("expected )");
    consume(")");
    return expr;
    } else {
    throw new SyntaxError("didn't expect '" + t + "'");
    }
    }
    Calculator parser - page 2 of 5 PrimaryExpr :
    Number
    Name
    ( Expr )
    Tuesday, September 3, 13

    View Slide

  74. function parsePrimaryExpr() {
    var t = peek();
    if (isNumber(t)) {
    consume(t);
    return out.number(t);
    } else if (isName(t)) {
    consume(t);
    return out.name(t);
    } else if (t === "(") {
    consume(t);
    var expr = parseExpr();
    if (peek() !== ")")
    throw new SyntaxError("expected )");
    consume(")");
    return expr;
    } else {
    throw new SyntaxError("didn't expect '" + t + "'");
    }
    }
    Calculator parser - page 2 of 5 PrimaryExpr :
    Number
    Name
    ( Expr )
    Tuesday, September 3, 13

    View Slide

  75. function parsePrimaryExpr() {
    var t = peek();
    if (isNumber(t)) {
    consume(t);
    return out.number(t);
    } else if (isName(t)) {
    consume(t);
    return out.name(t);
    } else if (t === "(") {
    consume(t);
    var expr = parseExpr();
    if (peek() !== ")")
    throw new SyntaxError("expected )");
    consume(")");
    return expr;
    } else {
    throw new SyntaxError("didn't expect '" + t + "'");
    }
    }
    Calculator parser - page 2 of 5 PrimaryExpr :
    Number
    Name
    ( Expr )
    Tuesday, September 3, 13

    View Slide

  76. function parseMulExpr() {
    var expr = parsePrimaryExpr();
    var t = peek();
    while (t === "*" || t === "/") {
    consume(t);
    var rhs = parsePrimaryExpr();
    if (t === "*")
    expr = out.mul(expr, rhs);
    else
    expr = out.div(expr, rhs);
    t = peek();
    }
    return expr;
    }
    Calculator parser - page 3 of 5
    MulExpr :
    PrimaryExpr ( * PrimaryExpr | / PrimaryExpr )*
    Tuesday, September 3, 13

    View Slide

  77. function parseMulExpr() {
    var expr = parsePrimaryExpr();
    var t = peek();
    while (t === "*" || t === "/") {
    consume(t);
    var rhs = parsePrimaryExpr();
    if (t === "*")
    expr = out.mul(expr, rhs);
    else
    expr = out.div(expr, rhs);
    t = peek();
    }
    return expr;
    }
    Calculator parser - page 3 of 5
    MulExpr :
    PrimaryExpr ( * PrimaryExpr | / PrimaryExpr )*
    Tuesday, September 3, 13

    View Slide

  78. function parseMulExpr() {
    var expr = parsePrimaryExpr();
    var t = peek();
    while (t === "*" || t === "/") {
    consume(t);
    var rhs = parsePrimaryExpr();
    if (t === "*")
    expr = out.mul(expr, rhs);
    else
    expr = out.div(expr, rhs);
    t = peek();
    }
    return expr;
    }
    Calculator parser - page 3 of 5
    MulExpr :
    PrimaryExpr ( * PrimaryExpr | / PrimaryExpr )*
    Tuesday, September 3, 13

    View Slide

  79. function parseMulExpr() {
    var expr = parsePrimaryExpr();
    var t = peek();
    while (t === "*" || t === "/") {
    consume(t);
    var rhs = parsePrimaryExpr();
    if (t === "*")
    expr = out.mul(expr, rhs);
    else
    expr = out.div(expr, rhs);
    t = peek();
    }
    return expr;
    }
    Calculator parser - page 3 of 5
    MulExpr :
    PrimaryExpr ( * PrimaryExpr | / PrimaryExpr )*
    Tuesday, September 3, 13

    View Slide

  80. function parseMulExpr() {
    var expr = parsePrimaryExpr();
    var t = peek();
    while (t === "*" || t === "/") {
    consume(t);
    var rhs = parsePrimaryExpr();
    if (t === "*")
    expr = out.mul(expr, rhs);
    else
    expr = out.div(expr, rhs);
    t = peek();
    }
    return expr;
    }
    Calculator parser - page 3 of 5
    MulExpr :
    PrimaryExpr ( * PrimaryExpr | / PrimaryExpr )*
    Tuesday, September 3, 13

    View Slide

  81. function parseMulExpr() {
    var expr = parsePrimaryExpr();
    var t = peek();
    while (t === "*" || t === "/") {
    consume(t);
    var rhs = parsePrimaryExpr();
    if (t === "*")
    expr = out.mul(expr, rhs);
    else
    expr = out.div(expr, rhs);
    t = peek();
    }
    return expr;
    }
    Calculator parser - page 3 of 5
    MulExpr :
    PrimaryExpr ( * PrimaryExpr | / PrimaryExpr )*
    Tuesday, September 3, 13

    View Slide

  82. function parseMulExpr() {
    var expr = parsePrimaryExpr();
    var t = peek();
    while (t === "*" || t === "/") {
    consume(t);
    var rhs = parsePrimaryExpr();
    if (t === "*")
    expr = out.mul(expr, rhs);
    else
    expr = out.div(expr, rhs);
    t = peek();
    }
    return expr;
    }
    Calculator parser - page 3 of 5
    MulExpr :
    PrimaryExpr ( * PrimaryExpr | / PrimaryExpr )*
    Tuesday, September 3, 13

    View Slide

  83. function parseMulExpr() {
    var expr = parsePrimaryExpr();
    var t = peek();
    while (t === "*" || t === "/") {
    consume(t);
    var rhs = parsePrimaryExpr();
    if (t === "*")
    expr = out.mul(expr, rhs);
    else
    expr = out.div(expr, rhs);
    t = peek();
    }
    return expr;
    }
    Calculator parser - page 3 of 5
    MulExpr :
    PrimaryExpr ( * PrimaryExpr | / PrimaryExpr )*
    Tuesday, September 3, 13

    View Slide

  84. function parseMulExpr() {
    var expr = parsePrimaryExpr();
    var t = peek();
    while (t === "*" || t === "/") {
    consume(t);
    var rhs = parsePrimaryExpr();
    if (t === "*")
    expr = out.mul(expr, rhs);
    else
    expr = out.div(expr, rhs);
    t = peek();
    }
    return expr;
    }
    Calculator parser - page 3 of 5
    MulExpr :
    PrimaryExpr ( * PrimaryExpr | / PrimaryExpr )*
    Tuesday, September 3, 13

    View Slide

  85. function parseMulExpr() {
    var expr = parsePrimaryExpr();
    var t = peek();
    while (t === "*" || t === "/") {
    consume(t);
    var rhs = parsePrimaryExpr();
    if (t === "*")
    expr = out.mul(expr, rhs);
    else
    expr = out.div(expr, rhs);
    t = peek();
    }
    return expr;
    }
    Calculator parser - page 3 of 5
    MulExpr :
    PrimaryExpr ( * PrimaryExpr | / PrimaryExpr )*
    Tuesday, September 3, 13

    View Slide

  86. function parseMulExpr() {
    var expr = parsePrimaryExpr();
    var t = peek();
    while (t === "*" || t === "/") {
    consume(t);
    var rhs = parsePrimaryExpr();
    if (t === "*")
    expr = out.mul(expr, rhs);
    else
    expr = out.div(expr, rhs);
    t = peek();
    }
    return expr;
    }
    Calculator parser - page 3 of 5
    MulExpr :
    PrimaryExpr ( * PrimaryExpr | / PrimaryExpr )*
    Tuesday, September 3, 13

    View Slide

  87. function parseMulExpr() {
    var expr = parsePrimaryExpr();
    var t = peek();
    while (t === "*" || t === "/") {
    consume(t);
    var rhs = parsePrimaryExpr();
    if (t === "*")
    expr = out.mul(expr, rhs);
    else
    expr = out.div(expr, rhs);
    t = peek();
    }
    return expr;
    }
    Calculator parser - page 3 of 5
    MulExpr :
    PrimaryExpr ( * PrimaryExpr | / PrimaryExpr )*
    Tuesday, September 3, 13

    View Slide

  88. function parseExpr() {
    var expr = parseMulExpr();
    var t = peek();
    while (t === "+" || t === "-") {
    consume(t);
    var rhs = parseMulExpr();
    if (t === "+")
    expr = out.add(expr, rhs);
    else
    expr = out.sub(expr, rhs);
    t = peek();
    }
    return expr;
    }
    Calculator parser - page 4 of 5
    Expr :
    MulExpr ( + MulExpr | - MulExpr )*
    Tuesday, September 3, 13

    View Slide

  89. Calculator parser - page 5 of 5
    var result = parseExpr();
    if (position !== tokens.length) {
    throw new SyntaxError(
    "unexpected '" + peek() + "'");
    }
    return result;
    }
    Tuesday, September 3, 13

    View Slide

  90. Calculator parser - page 5 of 5
    var result = parseExpr();
    if (position !== tokens.length) {
    throw new SyntaxError(
    "unexpected '" + peek() + "'");
    }
    return result;
    }
    Tuesday, September 3, 13

    View Slide

  91. Calculator parser - page 5 of 5
    var result = parseExpr();
    if (position !== tokens.length) {
    throw new SyntaxError(
    "unexpected '" + peek() + "'");
    }
    return result;
    }
    Tuesday, September 3, 13

    View Slide

  92. Calculator parser - page 5 of 5
    var result = parseExpr();
    if (position !== tokens.length) {
    throw new SyntaxError(
    "unexpected '" + peek() + "'");
    }
    return result;
    }
    Tuesday, September 3, 13

    View Slide

  93. Tuesday, September 3, 13

    View Slide

  94. Tuesday, September 3, 13

    View Slide

  95. Tuesday, September 3, 13

    View Slide

  96. IfStatement :
    if ( Expression ) Statement else Statement
    if ( Expression ) Statement
    Tuesday, September 3, 13

    View Slide

  97. IfStatement :
    if ( Expression ) Statement else Statement
    if ( Expression ) Statement
    Tuesday, September 3, 13

    View Slide

  98. IfStatement :
    if ( Expression ) Statement else Statement
    if ( Expression ) Statement
    PrimaryExpr :
    Number
    Name
    ( Expr )
    Tuesday, September 3, 13

    View Slide

  99. IfStatement :
    if ( Expression ) Statement else Statement
    if ( Expression ) Statement
    PrimaryExpr :
    Number
    Name
    ( Expr )
    function parsePrimaryExpr() {
    var t = peek();
    if (isNumber(t)) {
    consume(t);
    return out.number(t);
    } else if (isName(t)) {
    consume(t);
    return out.name(t);
    } else if (t === "(") {
    consume(t);
    var expr = parseExpr();
    if (peek() !== ")")
    throw new SyntaxError("expected )");
    consume(")");
    return expr;
    } else {
    throw new SyntaxError("didn't expect '" + t + "'");
    }
    }
    Tuesday, September 3, 13

    View Slide

  100. IfStatement :
    if ( Expression ) Statement else Statement
    if ( Expression ) Statement
    PrimaryExpr :
    Number
    Name
    ( Expr )
    function parsePrimaryExpr() {
    var t = peek();
    if (isNumber(t)) {
    consume(t);
    return out.number(t);
    } else if (isName(t)) {
    consume(t);
    return out.name(t);
    } else if (t === "(") {
    consume(t);
    var expr = parseExpr();
    if (peek() !== ")")
    throw new SyntaxError("expected )");
    consume(")");
    return expr;
    } else {
    throw new SyntaxError("didn't expect '" + t + "'");
    }
    }
    Tuesday, September 3, 13

    View Slide

  101. Tuesday, September 3, 13

    View Slide

  102. join me tomorrow
    for Compilers 101L
    Tuesday, September 3, 13

    View Slide