From fcc617dbf4d008612e5df08583445f307f9552ba Mon Sep 17 00:00:00 2001 From: "W. Cho" <wcho.dev@gmail.com> Date: Thu, 21 Dec 2023 18:42:54 +0900 Subject: [PATCH] fix token eating logic while parsing --- src/parser/index.test.ts | 38 ++++++++++++++++++++++++++++++++++++++ src/parser/index.ts | 11 ++++++++--- 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/src/parser/index.test.ts b/src/parser/index.test.ts index 4aab415..3dbd0a3 100644 --- a/src/parser/index.test.ts +++ b/src/parser/index.test.ts @@ -1015,4 +1015,42 @@ describe("parseProgram()", () => { it.each(cases)("parse $name", testParsing); }); + + describe("complex expression", () => { + const cases: { name: string, input: string, expected: Program }[] = [ + { + name: "assignment and arithmetic expression", + input: "변수1 = 1 ((변수1 + 변수1) * 변수1)", + expected: { + type: "program", + statements: [ + { + type: "expression statement", + expression: { + type: "assignment", + left: { type: "identifier", value: "변수1" }, + right: { type: "number node", value: 1 }, + }, + }, + { + type: "expression statement", + expression: { + type: "infix expression", + infix: "*", + left: { + type: "infix expression", + infix: "+", + left: { type: "identifier", value: "변수1" }, + right: { type: "identifier", value: "변수1" }, + }, + right: { type: "identifier", value: "변수1" }, + }, + }, + ], + }, + }, + ]; + + it.each(cases)("parse $name", testParsing); + }); }); diff --git a/src/parser/index.ts b/src/parser/index.ts index a6f767c..c23626e 100644 --- a/src/parser/index.ts +++ b/src/parser/index.ts @@ -278,13 +278,15 @@ export default class Parser { } private parseInfixExpression(left: Expression): Expression | null { + // note: do not eat token and just return null if not parsable const token = this.buffer.read(); - this.buffer.next(); // eat infix token if (token.type === "group delimiter" && token.value === "(") { if (left.type !== "function expression" && left.type !== "identifier") { - throw new Error(`expected function expression or identifier, but received ${left.type}`); + return null; } + + this.buffer.next(); // eat infix token return this.parseCall(left); } @@ -294,7 +296,9 @@ export default class Parser { const infix = token.value; if (infix === "=" && left.type === "identifier") { - return this.parseAssignment(left); + this.buffer.next(); // eat infix token + const a= this.parseAssignment(left); + return a; } if ( infix === "+" || @@ -308,6 +312,7 @@ export default class Parser { infix === ">=" || infix === "<=" ) { + this.buffer.next(); // eat infix token return this.parseArithmeticInfixExpression(left, infix); } return null;