UNPKG

@flowscripter/mpeg-sdl-parser

Version:

ISO/IEC 14496-34 Syntactic Description Language (MPEG SDL) parser implemented in TypeScript

136 lines (130 loc) 4.56 kB
import { Text } from "@codemirror/state"; import type { TreeCursor } from "@lezer/common"; import { InternalParseError } from "../../ParseError"; import { getChildNodesAndTokens, isAbstractNode, } from "../../util/nodeFactoryUtils"; import { NodeKind } from "../node/enum/node_kind"; import type { Token } from "../token/Token"; import type { AbstractStatement } from "../node/AbstractStatement"; import type { AbstractExpression } from "../node/AbstractExpression"; import { ForStatement } from "../node/ForStatement"; import { ComputedElementaryTypeDefinition } from "../node/ComputedElementaryTypeDefinition"; import { CompoundStatement } from "../node/CompoundStatement"; import { StatementKind } from "../node/enum/statement_kind"; export function getForStatement( cursor: TreeCursor, text: Text, ): ForStatement { const childNodesAndTokens = getChildNodesAndTokens(cursor, text); let expression1: AbstractExpression | undefined; let computedElementaryTypeDefinition: | ComputedElementaryTypeDefinition | undefined; let expression2: AbstractExpression | undefined; let expression3: AbstractExpression | undefined; let compoundStatement: CompoundStatement | undefined; let forKeyword: Token | undefined; let openParenthesisPunctuator: Token | undefined; let semicolon1Punctuator: Token | undefined; let semicolon2Punctuator: Token | undefined; let closeParenthesisPunctuator: Token | undefined; for (const childNodeOrToken of childNodesAndTokens) { if (isAbstractNode(childNodeOrToken)) { switch (childNodeOrToken.nodeKind) { case NodeKind.EXPRESSION: if (semicolon2Punctuator) { expression3 = childNodeOrToken as AbstractExpression; } else if (semicolon1Punctuator || computedElementaryTypeDefinition) { expression2 = childNodeOrToken as AbstractExpression; } else { expression1 = childNodeOrToken as AbstractExpression; } break; case NodeKind.STATEMENT: if ( (childNodeOrToken as AbstractStatement).statementKind === StatementKind.COMPOUND ) { compoundStatement = childNodeOrToken as CompoundStatement; } else if ( (childNodeOrToken as AbstractStatement).statementKind === StatementKind.COMPUTED_ELEMENTARY_TYPE_DEFINITION ) { computedElementaryTypeDefinition = childNodeOrToken as ComputedElementaryTypeDefinition; } else { throw new InternalParseError( `Unexpected statement kind: ${ (childNodeOrToken as AbstractStatement).statementKind }`, ); } break; default: throw new InternalParseError( `Unexpected node kind: ${NodeKind[childNodeOrToken.nodeKind]}`, ); } } else { switch (childNodeOrToken.text) { case "for": forKeyword = childNodeOrToken; break; case "(": openParenthesisPunctuator = childNodeOrToken; break; case ";": if (!semicolon1Punctuator && !computedElementaryTypeDefinition) { semicolon1Punctuator = childNodeOrToken; } else { semicolon2Punctuator = childNodeOrToken; } break; case ")": closeParenthesisPunctuator = childNodeOrToken; break; default: throw new InternalParseError( `Unexpected token: ${childNodeOrToken.text}`, ); } } } if (!compoundStatement) { throw new InternalParseError( "Expected argument compoundStatement to be defined", ); } if (!forKeyword) { throw new InternalParseError("Expected argument forKeyword to be defined"); } if (!openParenthesisPunctuator) { throw new InternalParseError( "Expected argument openParenthesisPunctuator to be defined", ); } if (!semicolon2Punctuator) { throw new InternalParseError( "Expected argument semicolon2Punctuator to be defined", ); } if (!closeParenthesisPunctuator) { throw new InternalParseError( "Expected argument closeParenthesisPunctuator to be defined", ); } return new ForStatement( expression1, computedElementaryTypeDefinition, expression2, expression3, compoundStatement, forKeyword, openParenthesisPunctuator, semicolon1Punctuator, semicolon2Punctuator, closeParenthesisPunctuator, ); }