Skip to content

Instantly share code, notes, and snippets.

@BRonen
Created March 5, 2025 21:14
Show Gist options
  • Save BRonen/8ea1d1681182692162ec8d0a19eb4bc6 to your computer and use it in GitHub Desktop.
Save BRonen/8ea1d1681182692162ec8d0a19eb4bc6 to your computer and use it in GitHub Desktop.
Interpretador feito com e sem parsing para árvores de sintaxe.
const example = "1 - 1 + 3 + 44 / 2";
const lexer = (source: string): string[] => {
const tokens: string[] = [];
let currentToken = "";
for (const char of source) {
if ([" ", "+", "-", "*", "/"].includes(char)) {
if (currentToken) tokens.push(currentToken);
if (char !== " ") tokens.push(char);
currentToken = "";
} else {
currentToken += char;
}
}
if(currentToken)
tokens.push(currentToken);
return tokens;
};
console.log(lexer(example));
const naiveInterpreter = (sourcetokens: string[]): number => {
let [token, ...tokens] = sourcetokens;
let op, v: string;
let result: number = Number(token);
while (tokens.length !== 0) {
[op, v, ...tokens] = tokens;
if (op === "+")
result += Number(v);
if (op === "-")
result -= Number(v);
if (op === "*")
result *= Number(v);
if (op === "/")
result /= Number(v);
}
return result;
};
console.log(naiveInterpreter(lexer(example)));
type Value = { node: "value"
value: number }
type LowOperator = { node: "multiply"
left: Value
right: LowOperator }
| { node: "division"
left: Value
right: LowOperator }
| Value;
type HighOperator = { node: "sum"
left: LowOperator
right: HighOperator }
| { node: "subtraction"
left: LowOperator
right: HighOperator }
| LowOperator;
const parseValue = (tokenList: string[]): [Value, string[]] => {
const [token, ...tokens] = tokenList;
return [{ node: "value", value: Number(token) }, tokens];
};
const parseLowOperator = (tokenList: string[]): [LowOperator, string[]] => {
const [left, tokens] = parseValue(tokenList);
if (tokens.length === 0) {
return [left, tokens];
}
const [operator, ...rest] = tokens;
if (operator === "*") {
const [right, remainingTokens] = parseLowOperator(rest);
return [{ node: "multiply", left, right }, remainingTokens];
}
if (operator === "/") {
const [right, remainingTokens] = parseLowOperator(rest);
return [{ node: "division", left, right }, remainingTokens];
}
return [left, tokens];
};
const parseHighOperator = (tokenList: string[]): [HighOperator, string[]] => {
const [left, tokens] = parseLowOperator(tokenList);
if (tokens.length === 0)
return [left, tokens];
const [operator, ...rest] = tokens;
if (operator === "+") {
const [right, remainingTokens] = parseHighOperator(rest);
return [{ node: "sum", left, right }, remainingTokens];
}
if (operator === "-") {
const [right, remainingTokens] = parseHighOperator(rest);
return [{ node: "subtraction", left, right }, remainingTokens];
}
return [left, tokens];
};
console.log(parseHighOperator(lexer(example)));
const evaluate = (tree: HighOperator): number => {
if (tree.node === "sum")
return evaluate(tree.left) + evaluate(tree.right);
if (tree.node === "subtraction")
return evaluate(tree.left) - evaluate(tree.right);
if (tree.node === "multiply")
return evaluate(tree.left) + evaluate(tree.right);
if (tree.node === "division")
return evaluate(tree.left) - evaluate(tree.right);
if (tree.node === "value")
return tree.value;
tree satisfies never;
return 0;
};
console.log(evaluate(parseHighOperator(lexer(example))[0]));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment