mirror of
https://github.com/hi-language/transpiler.git
synced 2026-01-14 00:28:05 +00:00
Fix: Reorder parser rules to fix initialization error
This commit is contained in:
158
src/parser.js
158
src/parser.js
@@ -7,6 +7,7 @@ class HiParser extends CstParser {
|
|||||||
|
|
||||||
const $ = this;
|
const $ = this;
|
||||||
|
|
||||||
|
// --- Top Level Rules ---
|
||||||
$.RULE('program', () => $.SUBRULE($.statements));
|
$.RULE('program', () => $.SUBRULE($.statements));
|
||||||
$.RULE('statements', () => $.MANY(() => $.SUBRULE($.statement)));
|
$.RULE('statements', () => $.MANY(() => $.SUBRULE($.statement)));
|
||||||
|
|
||||||
@@ -19,13 +20,6 @@ class HiParser extends CstParser {
|
|||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
$.RULE('expressionStatement', () => $.SUBRULE($.expression));
|
|
||||||
|
|
||||||
$.RULE('returnStatement', () => {
|
|
||||||
$.CONSUME(T.Caret);
|
|
||||||
$.OPTION(() => $.SUBRULE($.expression));
|
|
||||||
});
|
|
||||||
|
|
||||||
$.RULE('declaration', () => {
|
$.RULE('declaration', () => {
|
||||||
$.CONSUME(T.Identifier);
|
$.CONSUME(T.Identifier);
|
||||||
$.CONSUME(T.Colon);
|
$.CONSUME(T.Colon);
|
||||||
@@ -33,69 +27,21 @@ class HiParser extends CstParser {
|
|||||||
});
|
});
|
||||||
|
|
||||||
$.RULE('assignment', () => {
|
$.RULE('assignment', () => {
|
||||||
// Note: This only allows simple identifiers for now, not member expressions.
|
|
||||||
$.CONSUME(T.Identifier);
|
$.CONSUME(T.Identifier);
|
||||||
$.CONSUME(T.Eq);
|
$.CONSUME(T.Eq);
|
||||||
$.SUBRULE($.expression);
|
$.SUBRULE($.expression);
|
||||||
});
|
});
|
||||||
|
|
||||||
$.RULE('expression', () => $.SUBRULE($.conditionalExpression));
|
$.RULE('returnStatement', () => {
|
||||||
|
$.CONSUME(T.Caret);
|
||||||
$.RULE('conditionalExpression', () => {
|
$.OPTION(() => $.SUBRULE($.expression));
|
||||||
$.SUBRULE($.equalityExpression, { LABEL: 'condition' });
|
|
||||||
$.OPTION(() => {
|
|
||||||
$.CONSUME(T.Question);
|
|
||||||
$.SUBRULE2($.expression, { LABEL: 'consequent' });
|
|
||||||
$.OPTION2(() => {
|
|
||||||
$.CONSUME(T.Colon);
|
|
||||||
$.SUBRULE3($.expression, { LABEL: 'alternate' });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const buildBinaryExpressionRule = (name, higherPrecRule, operators) => {
|
$.RULE('expressionStatement', () => $.SUBRULE($.expression));
|
||||||
$.RULE(name, () => {
|
|
||||||
$.SUBRULE(higherPrecRule, { LABEL: 'left' });
|
|
||||||
$.MANY(() => {
|
|
||||||
$.CONSUME($.OR(operators));
|
|
||||||
$.SUBRULE2(higherPrecRule, { LABEL: 'right' });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
buildBinaryExpressionRule('equalityExpression', $.additiveExpression, [
|
// --- Expressions (ordered by precedence, highest to lowest) ---
|
||||||
{ ALT: () => T.EqEq }
|
|
||||||
]);
|
|
||||||
|
|
||||||
buildBinaryExpressionRule('additiveExpression', $.multiplicativeExpression, [
|
|
||||||
{ ALT: () => T.Plus }, { ALT: () => T.Minus }
|
|
||||||
]);
|
|
||||||
|
|
||||||
buildBinaryExpressionRule('multiplicativeExpression', $.callExpression, [
|
|
||||||
{ ALT: () => T.Star }, { ALT: () => T.Slash }
|
|
||||||
]);
|
|
||||||
|
|
||||||
$.RULE('callExpression', () => {
|
|
||||||
$.SUBRULE($.memberExpression, { LABEL: 'callee' });
|
|
||||||
$.MANY(() => {
|
|
||||||
$.CONSUME(T.LParen);
|
|
||||||
$.OPTION(() => $.SUBRULE($.argumentList));
|
|
||||||
$.CONSUME(T.RParen);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
$.RULE('argumentList', () => $.SEPERATED_LIST($.expression, T.Comma));
|
|
||||||
|
|
||||||
$.RULE('memberExpression', () => {
|
|
||||||
$.SUBRULE($.primary, { LABEL: 'object' });
|
|
||||||
$.MANY(() => {
|
|
||||||
$.OR([
|
|
||||||
{ ALT: () => { $.CONSUME(T.Dot); $.CONSUME(T.Identifier); }},
|
|
||||||
{ ALT: () => { $.CONSUME(T.LBracket); $.SUBRULE($.expression); $.CONSUME(T.RBracket); }}
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
|
// Primary is the highest precedence expression.
|
||||||
$.RULE('primary', () => {
|
$.RULE('primary', () => {
|
||||||
$.OR([
|
$.OR([
|
||||||
{ ALT: () => $.SUBRULE($.literal) },
|
{ ALT: () => $.SUBRULE($.literal) },
|
||||||
@@ -112,12 +58,32 @@ class HiParser extends CstParser {
|
|||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Components used by Primary
|
||||||
$.RULE('literal', () => $.OR([
|
$.RULE('literal', () => $.OR([
|
||||||
{ ALT: () => $.CONSUME(T.Number) },
|
{ ALT: () => $.CONSUME(T.Number) },
|
||||||
{ ALT: () => $.CONSUME(T.String) },
|
{ ALT: () => $.CONSUME(T.String) },
|
||||||
{ ALT: () => $.CONSUME(T.Null) }
|
{ ALT: () => $.CONSUME(T.Null) }
|
||||||
]));
|
]));
|
||||||
|
|
||||||
|
$.RULE('arrayLiteral', () => {
|
||||||
|
$.CONSUME(T.LBracket);
|
||||||
|
$.OPTION(() => $.SEPERATED_LIST($.expression, T.Comma));
|
||||||
|
$.CONSUME(T.RBracket);
|
||||||
|
});
|
||||||
|
|
||||||
|
$.RULE('parameterList', () => {
|
||||||
|
$.CONSUME(T.LParen);
|
||||||
|
$.OPTION(() => $.SEPERATED_LIST(T.Identifier, T.Comma));
|
||||||
|
$.CONSUME(T.RParen);
|
||||||
|
});
|
||||||
|
|
||||||
|
$.RULE('block', () => {
|
||||||
|
$.OPTION(() => $.SUBRULE($.parameterList));
|
||||||
|
$.CONSUME(T.LBrace);
|
||||||
|
$.SUBRULE($.statements);
|
||||||
|
$.CONSUME(T.RBrace);
|
||||||
|
});
|
||||||
|
|
||||||
$.RULE('arrowExpression', () => {
|
$.RULE('arrowExpression', () => {
|
||||||
$.SUBRULE($.parameterList);
|
$.SUBRULE($.parameterList);
|
||||||
$.CONSUME(T.Arrow);
|
$.CONSUME(T.Arrow);
|
||||||
@@ -127,24 +93,68 @@ class HiParser extends CstParser {
|
|||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
$.RULE('arrayLiteral', () => {
|
// MemberExpression consumes a Primary.
|
||||||
$.CONSUME(T.LBracket);
|
$.RULE('memberExpression', () => {
|
||||||
$.OPTION(() => $.SEPERATED_LIST($.expression, T.Comma));
|
$.SUBRULE($.primary, { LABEL: 'object' });
|
||||||
$.CONSUME(T.RBracket);
|
$.MANY(() => {
|
||||||
|
$.OR([
|
||||||
|
{ ALT: () => { $.CONSUME(T.Dot); $.CONSUME(T.Identifier); }},
|
||||||
|
{ ALT: () => { $.CONSUME(T.LBracket); $.SUBRULE($.expression); $.CONSUME(T.RBracket); }}
|
||||||
|
]);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
$.RULE('block', () => {
|
// CallExpression consumes a MemberExpression.
|
||||||
$.OPTION(() => $.SUBRULE($.parameterList));
|
$.RULE('callExpression', () => {
|
||||||
$.CONSUME(T.LBrace);
|
$.SUBRULE($.memberExpression, { LABEL: 'callee' });
|
||||||
$.SUBRULE($.statements);
|
$.MANY(() => {
|
||||||
$.CONSUME(T.RBrace);
|
|
||||||
});
|
|
||||||
|
|
||||||
$.RULE('parameterList', () => {
|
|
||||||
$.CONSUME(T.LParen);
|
$.CONSUME(T.LParen);
|
||||||
$.OPTION(() => $.SEPERATED_LIST(T.Identifier, T.Comma));
|
$.OPTION(() => $.SUBRULE($.argumentList));
|
||||||
$.CONSUME(T.RParen);
|
$.CONSUME(T.RParen);
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$.RULE('argumentList', () => $.SEPERATED_LIST($.expression, T.Comma));
|
||||||
|
|
||||||
|
// Binary Expressions are defined with a helper.
|
||||||
|
const buildBinaryExpressionRule = (name, higherPrecRule, operators) => {
|
||||||
|
$.RULE(name, () => {
|
||||||
|
$.SUBRULE(higherPrecRule, { LABEL: 'left' });
|
||||||
|
$.MANY(() => {
|
||||||
|
$.CONSUME($.OR(operators));
|
||||||
|
$.SUBRULE2(higherPrecRule, { LABEL: 'right' });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Define binary expressions from highest to lowest precedence.
|
||||||
|
buildBinaryExpressionRule('multiplicativeExpression', $.callExpression, [
|
||||||
|
{ ALT: () => T.Star }, { ALT: () => T.Slash }
|
||||||
|
]);
|
||||||
|
|
||||||
|
buildBinaryExpressionRule('additiveExpression', $.multiplicativeExpression, [
|
||||||
|
{ ALT: () => T.Plus }, { ALT: () => T.Minus }
|
||||||
|
]);
|
||||||
|
|
||||||
|
buildBinaryExpressionRule('equalityExpression', $.additiveExpression, [
|
||||||
|
{ ALT: () => T.EqEq }
|
||||||
|
]);
|
||||||
|
|
||||||
|
// ConditionalExpression consumes an EqualityExpression.
|
||||||
|
$.RULE('conditionalExpression', () => {
|
||||||
|
$.SUBRULE($.equalityExpression, { LABEL: 'condition' });
|
||||||
|
$.OPTION(() => {
|
||||||
|
$.CONSUME(T.Question);
|
||||||
|
$.SUBRULE2($.expression, { LABEL: 'consequent' });
|
||||||
|
$.OPTION2(() => {
|
||||||
|
$.CONSUME(T.Colon);
|
||||||
|
$.SUBRULE3($.expression, { LABEL: 'alternate' });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Expression is the lowest precedence rule, forming the entry point for the chain.
|
||||||
|
$.RULE('expression', () => $.SUBRULE($.conditionalExpression));
|
||||||
|
|
||||||
this.performSelfAnalysis();
|
this.performSelfAnalysis();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user