Skip to content

Commit

Permalink
⬆️ UPDATE 语法分析
Browse files Browse the repository at this point in the history
  • Loading branch information
sunwu51 committed Dec 28, 2024
1 parent 564aabc commit bde4b46
Show file tree
Hide file tree
Showing 25 changed files with 2,202 additions and 3,428 deletions.
454 changes: 0 additions & 454 deletions 24.11/parser.mjs

This file was deleted.

47 changes: 47 additions & 0 deletions 24.11/parser_class_v1.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
export class Sentence {
constructor() {
this.endPos = -1;
}
}

export class VarSentence extends Sentence {
constructor(name, value, endPos) {
super();
this.name = name; // name本身其实也是个表达式
this.value = value; // 这里的value是个表达式
this.endPos = endPos;
}
}

export class ReturnSentence extends Sentence {
constructor(value, endPos) {
super();
this.value = value; // 这里的value也是表达式
this.endPos = endPos;
}
}

export class BlockSentence extends Sentence {
constructor(sentences, endPos) {
super();
this.sentences = sentences;
this.endPos = endPos;
}
}

export class ExpressionSentence extends Sentence {
constructor(expression, endPos) {
super();
this.expression = expression; // 这里的expression也是表达式
this.endPos = endPos;
}
}

export class AstNode {}

export class IdentifierAstNode extends AstNode {
constructor(token) {
super();
this.token = token;
}
}
92 changes: 92 additions & 0 deletions 24.11/parser_class_v2.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
export class Sentence {
}

export class VarSentence extends Sentence {
constructor(name, value) {
super();
this.name = name; // name本身其实也是个表达式
this.value = value; // 这里的value是个表达式
}
toString() {
return `var ${this.name} = ${this.value.toString()};`;
}
}

export class ReturnSentence extends Sentence {
constructor(value) {
super();
this.value = value; // 这里的value也是表达式
}
toString() {
return `return ${this.value.toString()};`;
}
}

export class BlockSentence extends Sentence {
constructor(sentences) {
super();
this.sentences = sentences;
}
toString() {
return `{
${this.sentences.map(it=>it.toString()).join('\n')}
}`
}
}

export class ExpressionSentence extends Sentence {
constructor(expression) {
super();
this.expression = expression; // 这里的expression也是表达式
}
toString() {
return this.expression.toString() + ";";
}
}

export const precedenceMap = {
'EOF': 0,
'+': 1,
'-': 1,
'*': 2,
'/': 2
}
export class AstNode {
constructor(full) {
if (full === undefined) this.full = false;
this.full = full;
}
toString() {
return `EmptyASTNode`;
}
}
export class IdentifierAstNode extends AstNode {
constructor(token) {
super(true);
this.token = token;
}
toString() {
return this.token.value;
}
}
export class NumberAstNode extends AstNode {
constructor(value) {
super(true);
this.value = value;
}
toString() {
return this.value;
}
}
export class InfixOperatorAstNode extends AstNode {
constructor(token) {
super(false);
this.op = token;
this.left = null;
this.right = null;
this.precedence = precedenceMap[token.value];
}
toString() {
return `(${this.left.toString()} ${this.op.value} ${this.right.toString()})`;
}
}
247 changes: 247 additions & 0 deletions 24.11/parser_class_v3.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,247 @@
export class Sentence {
}

export class VarSentence extends Sentence {
constructor(name, value) {
super();
this.name = name; // name本身其实也是个表达式
this.value = value; // 这里的value是个表达式
}
toString() {
return `var ${this.name} = ${this.value.toString()};`;
}
}

export class ReturnSentence extends Sentence {
constructor(value) {
super();
this.value = value; // 这里的value也是表达式
}
toString() {
return `return ${this.value.toString()};`;
}
}

export class BlockSentence extends Sentence {
constructor(sentences) {
super();
this.sentences = sentences;
}
toString() {
return `{
${this.sentences.map(it=>it.toString()).join('\n')}
}`
}
}

export class ExpressionSentence extends Sentence {
constructor(expression) {
super();
this.expression = expression; // 这里的expression也是表达式
}
toString() {
return this.expression.toString() + ";";
}
}

export const precedenceMap = {
'EOF': 0,
'=': 10,
'||': 11, '&&': 12, '^': 13,
'==': 14, '!=': 14,
'<': 15, '<=': 15, '>': 15, '>=': 15,
'<<': 16, '>>': 16, '>>>': 16,
'+': 17, '-': 17,
'*': 18, '/': 18, '%': 18,
}
export const prefixPrecedenceMap = {
'-': 100,
'!': 100,
'~': 100,
'+': 100,
'++': 100,
'--': 100
}
export const postfixPrecedenceMap = {
'++': 200,
'--': 200
}
export class AstNode {
toString() {
return `EmptyASTNode`;
}
}
export class NumberAstNode extends AstNode {
constructor(token) {
super();
this.token = token;
}

toString() {
return this.token.value;
}
}
// 变量名/函数名字面量
export class IdentifierAstNode extends AstNode {
constructor(token) {
super();
this.token = token;
}

toString() {
return this.token.value;
}
}
// null字面量
export class NullAstNode extends AstNode {
toString() {
return "null";
}
}

// 字符串字面量
export class StringAstNode extends AstNode {
constructor(token) {
super();
this.token = token;
}
toString() {
return this.token.value;
}
}
// boolean字面量
export class BooleanAstNode extends AstNode {
constructor(token) {
super();
this.token = token;
}
toString() {
return this.token.value;
}
}
// 中缀操作符节点
export class InfixOperatorAstNode extends AstNode {
constructor(token) {
super();
this.op = token;
this.left = null;
this.right = null;
this.precedence = precedenceMap[token.value];
if (this.precedence === undefined) {
throw new Error(`Invalid infix operator: ${token.value}`);
}
}
toString() {
return `(${this.left.toString()} ${this.op.value} ${this.right.toString()})`;
}
}
// 前缀操作符
export class PrefixOperatorAstNode extends AstNode {
constructor(token, right) {
super(false);
this.op = token;
this.right = right;
this.precedence = prefixPrecedenceMap[token.value];
if (this.precedence === undefined) {
throw new Error(`Invalid prefix operator: ${token.value}`);
}
}
toString() {
return `(${this.op.value} ${this.right.toString()})`;
}
}
// 后缀操作符
export class PostfixOperatorAstNode extends AstNode {
constructor(token, left) {
super(false);
this.op = token;
this.left = left;
this.precedence = postfixPrecedenceMap[token.value];
if (this.precedence === undefined) {
throw new Error(`Invalid postfix operator: ${token.value}`);
}
}
toString() {
return `(${this.left.toString()} ${this.op.value})`;
}
}
// 函数声明
export class FunctionDeclarationAstNode extends AstNode {
constructor(params, body) {
super();
this.params = params;
this.body = body;
}
toString() {
return `function(${this.params.join(',')})${this.body.toString()}`;
}
}
// 函数调用
export class FunctionCallAstNode extends AstNode {
constructor(name, args) {
super();
this.name = name;
this.args = args; // args是ast数组
}
toString() {
return `${this.name.toString()}(${this.args.map(it=>it.toString()).join(',')})`
}
}
// 分组节点
export class GroupAstNode extends AstNode {
constructor(exp) {
super();
this.exp = exp;
}
toString() {
// 因为小括号已经在运算符的toString中使用了,这里为了更好的凸显使用中文中括号
return `【${this.exp.toString()}】`
}
}
export class IfSentence extends Sentence {
constructor(condition, ifBody, elseBody) {
super("IF");
this.condition = condition;
this.ifBody = ifBody;
this.elseBody = elseBody;
}
toString() {
return `if ${this.condition.toString()} ${this.ifBody.toString()} ${this.elseBody ? `else ${this.elseBody.toString()}` : ""}
`
}
}

export class ForSentence extends Sentence {
constructor(init, condition, step, body) {
super();
this.init = init;
this.condition = condition;
this.step = step;
this.body = body;
}
toString() {
return `for(${this.init.toString()} ${this.condition.toString()} ${this.step.toString()})${this.body.toString()}`
}
}
export class BreakSentence extends Sentence {
constructor(token) {
super();
this.token = token;
}
toString() { return "break;";}
}
export class ContinueSentence extends Sentence {
constructor(token) {
super();
this.token = token;
}
toString() { return "continue;";}
}
export class EmptySentence extends Sentence {
constructor() {
super("EMPTY");
}
toString() {
return "";
}
}
Loading

0 comments on commit bde4b46

Please sign in to comment.