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

8341c5bff3dcbd8ed34d9d68bd4169f2?s=128

Jason Orendorff

August 17, 2013
Tweet

Transcript

  1. 17 August 2013 Compilers 101 An introduction to programming languages

    and parsing Tuesday, September 3, 13
  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
  3. gist.io/6256943 Tuesday, September 3, 13

  4. Tuesday, September 3, 13

  5. Tuesday, September 3, 13

  6. green big ball Tuesday, September 3, 13

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

  8. Tuesday, September 3, 13

  9. A compiler is Tuesday, September 3, 13

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

    3, 13
  11. A compiler is a program that translates code from one

    language to another. Tuesday, September 3, 13
  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
  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
  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
  15. Tuesday, September 3, 13

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

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

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

    It’s not record-based. Tuesday, September 3, 13
  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
  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
  21. Tuesday, September 3, 13

  22. when flag clicked forever point towards mouse-pointer if move 3

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

    * speed steps not touching mouse-pointer ? then Tuesday, September 3, 13
  24. Inside a compiler Tuesday, September 3, 13

  25. Inside a compiler Tuesday, September 3, 13

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

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

    13
  28. front end (parsing, analysis) back end (code generation) Inside a

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

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

    a compiler Tuesday, September 3, 13
  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
  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
  33. Inside a front end Tuesday, September 3, 13

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

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

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

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

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

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

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

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

    12 x ['12', '*', 'x'] out.number('12') Tuesday, September 3, 13
  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
  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
  44. IfStatement : if ( Expression ) Statement else Statement if

    ( Expression ) Statement Tuesday, September 3, 13
  45. Statement : Block VariableStatement EmptyStatement ExpressionStatement IfStatement IterationStatement ContinueStatement BreakStatement

    ReturnStatement WithStatement LabelledStatement Tuesday, September 3, 13
  46. Tuesday, September 3, 13

  47. PrimaryExpr : Number Name ( Expr ) MulExpr : PrimaryExpr

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

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

    ( * PrimaryExpr | / PrimaryExpr )* Expr : MulExpr ( + MulExpr | - MulExpr )* out.number("3") out.name("pi") Tuesday, September 3, 13
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  93. Tuesday, September 3, 13

  94. Tuesday, September 3, 13

  95. Tuesday, September 3, 13

  96. IfStatement : if ( Expression ) Statement else Statement if

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

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

    ( Expression ) Statement PrimaryExpr : Number Name ( Expr ) Tuesday, September 3, 13
  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
  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
  101. Tuesday, September 3, 13

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