Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Zirconium Parser v2.0 #17

Draft
wants to merge 45 commits into
base: master
Choose a base branch
from
Draft
Changes from 1 commit
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
b702bf4
Begin work on parser rewrite
Vorlias Jan 28, 2022
cbc6ce1
Working on the new improved parser
Vorlias Jan 28, 2022
47c8c19
Add function call
Vorlias Jan 28, 2022
1a98ca3
Add inline expression for simple calls, better handling
Vorlias Jan 28, 2022
d9d71fd
Object literals
Vorlias Jan 28, 2022
3706e72
ObjectLiteral -> ObjectLiteralExpression
Vorlias Jan 28, 2022
3c7cf24
bang! call + array index call support
Vorlias Jan 28, 2022
d73f634
Fixes + EBNF file
Vorlias Jan 28, 2022
9e96609
Update syntax.ebnf
Vorlias Jan 28, 2022
98941dd
Parser updates
Vorlias Feb 16, 2022
b9753a5
More refactoring
Vorlias Feb 16, 2022
115cc34
Bump to 2.0
Vorlias Feb 16, 2022
4cf5cba
Work
Vorlias Feb 16, 2022
1f4a905
Fixes to parser positionings
Vorlias Feb 16, 2022
78f01e2
Updated Identifier parsing, bang call endPos fixed
Vorlias Feb 16, 2022
b09f529
Huge changes
Vorlias Mar 18, 2022
5aaa2e8
Fix up element access expressions
Vorlias Mar 18, 2022
b60a1f1
Fix call expressions
Vorlias Mar 18, 2022
53db8b7
Fix inline call variables
Vorlias Mar 18, 2022
a7bf232
More fixes
Vorlias Mar 18, 2022
bbc57be
More changes
Vorlias Mar 18, 2022
d04a36a
Fixes + other changes
Vorlias Aug 14, 2022
b914508
More work
Vorlias Aug 14, 2022
2db4fb5
Bump to roblox-ts 2.0
Vorlias Oct 12, 2022
d4e4c02
Runtime changes
Vorlias Oct 12, 2022
07dfc52
More changes
Vorlias Oct 12, 2022
1c66bb1
Changes
Vorlias Jan 16, 2023
70a94e2
more language changes
Vorlias May 29, 2023
f7b52c3
Rename setting
Vorlias May 29, 2023
f2afcde
A few other adjustments
Vorlias May 29, 2023
ebd654a
parseAst changes
Vorlias May 29, 2023
cf38998
Correctly parse fn
Vorlias Jun 8, 2023
fdf7c0b
Fix bug with command calls
Vorlias Jun 8, 2023
7d5d6c2
Force consumption of ElementEnd token
Vorlias Jun 8, 2023
1b0aa8f
More lib changes
Vorlias Jun 10, 2023
0a769b7
Support function expression
Vorlias Jun 10, 2023
b7aa63d
Experimental arrow funcs
Vorlias Jun 10, 2023
cd4a477
ok change look ahead thingy
Vorlias Jun 10, 2023
a22630b
single statement support for arrow func
Vorlias Jun 10, 2023
8943d44
Legacy command syntax is now an option
Vorlias Jun 10, 2023
5ad873f
Transform macros for debugging
Vorlias Jun 10, 2023
b88b197
transformer lol
Vorlias Jun 10, 2023
d509184
more
Vorlias Jun 16, 2023
a8b756e
Userdata changes
Vorlias Jun 19, 2023
1fc76df
code changes
Vorlias Jun 19, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Updated Identifier parsing, bang call endPos fixed
Vorlias committed Feb 16, 2022
commit 78f01e261131fc2b1ebd5ab8aee9b2e691ee8fc5
76 changes: 36 additions & 40 deletions lib/Ast/ParserV2/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Option, Result } from "@rbxts/rust-classes";
import { ZrLexer } from "Ast";
import { ArrayIndexExpression, ArrayLiteralExpression, CallExpression, DeclarationStatement, EnumDeclarationStatement, EnumItemExpression, Expression, FunctionDeclaration, Identifier, LiteralExpression, NamedDeclaration, ZrNode, ZrNodeKinds, ObjectLiteralExpression, ParameterDeclaration, ParenthesizedExpression, PropertyAccessExpression, PropertyAssignment, SimpleCallExpression, SourceBlock, SourceFile, Statement, ZrEditNode } from "Ast/Nodes/NodeTypes";
import { ArrayIndexExpression, ArrayLiteralExpression, CallExpression, DeclarationStatement, EnumDeclarationStatement, EnumItemExpression, Expression, FunctionDeclaration, Identifier, LiteralExpression, NamedDeclaration, ZrNode, ZrNodeKinds, ObjectLiteralExpression, ParameterDeclaration, ParenthesizedExpression, PropertyAccessExpression, PropertyAssignment, SimpleCallExpression, SourceBlock, SourceFile, Statement, ZrEditNode, StringLiteral } from "Ast/Nodes/NodeTypes";
import { updateHasNodeError } from "Ast/Nodes/Update";
import Grammar, { Keywords, OperatorTokenId, SpecialTokenId } from "Ast/Tokens/Grammar";
import { ArrayIndexToken, IdentifierToken, isToken, KeywordToken, PropertyAccessToken, SpecialToken, StringToken, ZrToken, TokenTypes, ZrTokenFlag, ZrTokenType } from "Ast/Tokens/Tokens";
@@ -249,8 +249,7 @@ export class ZrParserV2 {
parameterIndex++;

const parameter = this.createNode(ZrNodeKind.Parameter);
const id = this.consumeToken(ZrTokenType.Identifier);
parameter.name = this.parseId(id) as Identifier;
parameter.name = this.parseIdentifier();
parameter.type = factory.createKeywordTypeNode(ZrTypeKeyword.Any);

parameters.push(this.finishNode(parameter));
@@ -309,8 +308,7 @@ export class ZrParserV2 {
this.consumeToken(ZrTokenType.Keyword, Keywords.ENUM); // consume 'enum'

if (this.isToken(ZrTokenType.Identifier)) {
const id = this.consumeToken(ZrTokenType.Identifier);
enumStatement.name = this.parseId(id) as Identifier;
enumStatement.name = this.parseIdentifier();
enumStatement.values = this.parseEnumItems();
} else {
this.parserErrorAtCurrentToken(DiagnosticErrors.IdentifierExpected);
@@ -378,46 +376,42 @@ export class ZrParserV2 {
return token !== undefined && (isToken(token, ZrTokenType.PropertyAccess) || isToken(token, ZrTokenType.ArrayIndex) || isToken(token, ZrTokenType.Identifier));
}

/** @deprecated */
private parseId(token: IdentifierToken | PropertyAccessToken | ArrayIndexToken) {
if (isToken(token, ZrTokenType.PropertyAccess)) {
let id: Identifier | PropertyAccessExpression | ArrayIndexExpression = factory.createIdentifier(token.value);
for (const name of token.properties) {
if (name.match("^%d+$")[0]) {
id = factory.createArrayIndexExpression(id, factory.createNumberNode(tonumber(name)!));
} else {
id = factory.createPropertyAccessExpression(id, factory.createIdentifier(name));
}
}
return id;
} else {
return factory.createIdentifier(token.value);
}
}
/**
* Parses the next identifier as a {@link StringLiteral}
* @returns
*/
private parseIdentifierAsString(): StringLiteral {
const stringNode = this.createNode(ZrNodeKind.String);

private parseIdentifierToString() {
if (this.isToken(ZrTokenType.Identifier)) {
const stringNode = this.createNode(ZrNodeKind.String);
const idToken = this.consumeToken(ZrTokenType.Identifier);
stringNode.text = idToken.value;

const idToken = this.consumeToken(ZrTokenType.Identifier);
stringNode.text = idToken.value;
return this.finishNode(stringNode);
}

return this.finishNode(stringNode);
} else {
throw `Weird exception`;
}
/**
* Parses only identifier nodes
* @returns
*/
private parseIdentifier(): Identifier {
const identifier = this.createNode(ZrNodeKind.Identifier);
const identifierToken = this.consumeToken(ZrTokenType.Identifier);
identifier.name = identifierToken.value;
return this.finishNode(identifier);
}

private parseIdentifierLike() {
/**
* Parses any identifying like nodes
* @returns
*/
private parseIdentifierLike(): Identifier | PropertyAccessExpression | ArrayIndexExpression {
if (this.isToken(ZrTokenType.PropertyAccess)) {
// TODO: This should use identifiers, split by `.` special operator
throw `TODO: Fix support for PropertyAccess`;
} else if(this.isToken(ZrTokenType.ArrayIndex)) {
throw `TODO: Fix support for ArrayIndex`;
} else {
const identifier = this.createNode(ZrNodeKind.Identifier);
const identifierToken = this.consumeToken(ZrTokenType.Identifier);
identifier.name = identifierToken.value;
return this.finishNode(identifier);
return this.parseIdentifier();
}
}

@@ -608,9 +602,10 @@ export class ZrParserV2 {
// Handle bang calls e.g. 'execute!'
if (this.isNextToken(ZrTokenType.Operator, "!") && !useSimpleCallSyntax) {
const callExpression = this.createNode(ZrNodeKind.CallExpression);
callExpression.isSimpleCall = true;
callExpression.expression = this.parseIdentifierLike();
this.consumeToken();
return callExpression;
const bang = this.consumeToken(ZrTokenType.Operator, "!");
return this.finishNode(callExpression, bang.startPos);
}


@@ -634,7 +629,7 @@ export class ZrParserV2 {

// If we're currently inside a command call, we'll treat identifiers as strings.
if (useSimpleCallSyntax) {
return this.parseIdentifierToString();
return this.parseIdentifierAsString();
}

// Otherwise, we'll return this as a regular identifier.
@@ -675,9 +670,10 @@ export class ZrParserV2 {
}

const expressionStatement = this.createNode(ZrNodeKind.ExpressionStatement);
expressionStatement.expression = this.mutateExpression(this.mutateExpression(this.parseNextExpression()));
const expression = this.mutateExpression(this.mutateExpression(this.parseNextExpression()));
expressionStatement.expression = expression;

return this.finishNode(expressionStatement);
return this.finishNode(expressionStatement, expression.endPos);
}

private skipAllWhitespace() {
11 changes: 8 additions & 3 deletions lib/Ast/Utility/PrettyPrintNodes.ts
Original file line number Diff line number Diff line change
@@ -19,9 +19,9 @@ function prettyPrintNodes(nodes: ZrNode[], prefix = "", verbose = false) {
if (node.isUnterminated) {
print(prefix, "Unterminated String");
}
} else if (isNode(node, CmdSyntaxKind.CallExpression) || isNode(node, CmdSyntaxKind.SimpleCallExpression)) {
} else if (isNode(node, CmdSyntaxKind.CallExpression)) {
if (verbose) {
print(prefix, CmdSyntaxKind[node.kind], `'${node.rawText}'`, `[${node.startPos}:${node.endPos}]`, "{");
print(prefix, CmdSyntaxKind[node.kind], node.isSimpleCall ? "<!>" : "<()>", `'${node.rawText}'`, `[${node.startPos}:${node.endPos}]`, "{");
} else {
print(prefix, CmdSyntaxKind[node.kind], "{");
}
@@ -148,7 +148,12 @@ function prettyPrintNodes(nodes: ZrNode[], prefix = "", verbose = false) {
prettyPrintNodes([node.option, node.expression], prefix + "\t", verbose);
print(prefix, "}");
} else if (isNode(node, CmdSyntaxKind.ExpressionStatement)) {
print(prefix, "ExpressionStatement", "{");
if (verbose) {
print(prefix, "ExpressionStatement", `'${node.rawText}'`, `[${node.startPos}:${node.endPos}]`, "{");
} else {
print(prefix, "ExpressionStatement", "{");
}

prettyPrintNodes([node.expression], prefix + "\t", verbose);
print(prefix, "}");
print("");