// This grammar serves a documentation for the LL(N) parser // implemented a recursive descent parser // Grammar can not be LL(1). Needs more than the next tokens at several places // Example: let name = $some_var vs // let name = $join(@some_array) // In the same context the string sigil can signal a reference to variable or the call of a method ! // N has to be determined yet. // Grammar rules derived from the code snippets of the ion online manual. // Link: https://doc.redox-os.org/ion-manual/introduction.html // Words beginning with an underscore are non-terminal. Non-terminal are tokens provided by // the scanner phase // _Anything is every possible non-terminal // Rules ending with an equal sign, are elements of the syntax tree. // This grammar is not designed to be unambiguous so far. // !! is checkpoint marker at which the parser can continue after encountering a parser error. Program -> Statement* ~ EOI Statement -> HorizontalNoise* ~ ( ( NoCommend ~ Commend? ) | Commend ) NoCommend -> ( IfBlock | WhileBlock | ForBlock | MatchBlock | VariableDeclaration | ExportDeclaration | CommandChain ) ~ HorizontalNoise* ~ EndOfStatement ~ !! EndOfStatement -> _Semicolon | NewLine | EOI // Note: // ( LogicalChainOperator ~ noise* ~ PipedCommands )* // ^ // `noise*` in the | // Supports syntax lie: // test $bar = "bar" && // echo "foobar was found" CommandChain -> PipedCommands ~ ( LogicalChainOperator ~ noise* ~ PipedCommands )* ~ DetachOperator? PipedCommands -> CommandExpression ~ ( PipeOperator ~ CommandExpression )* CommandExpression -> Command ~ ( HorizontalNoise* ~ CommandValue )* ~ RedirectToFile* CommandValue = !PipeOperator ~ Value LogicalChainOperator -> ( LogicalAnd | LogicalOr ) LogicalAnd -> _AndOperator LogicalOr -> _OrOperator PipeOperator -> ( PipeStdOut | PipeStdErr | PipeBoth ) RedirectOperator -> ( RedirectInput | RedirectOutOperator ) RedirectOutOperator > ( RedirectStdout | RedirectStderr | RedirectBoth ) ~ AppendRedirect? RedirectToFile -> RedirectOperator ~ File File -> _Word HorizontalNoise -> _WhiteSpace | _Tab Noise -> HorizontalNoise | _NewLine AppendRedirect -> _ToStdOut RedirectStdout -> _ToStdOut RedirectStderr -> _ToStdErr RedirectBoth -> _ToStdBoth RedirectInput -> _FileInputOpreator PipeStdOut -> _PipeStdOut PipeStdErr -> _PipeStdErr PipeBoth -> _PipeBoth DetachOperator -> ( DetachProcessOperator | DisownOperator ) DetachProcessOperator -> _Ampersand DisownOperator -> _Disown VariableDeclaration -> _Let ~ VariableStatement ExportDeclaration -> _Export ~ VariableName DocString -> _StartDocString ~ ContentOfCommend Commend -> _Hash ~ ContentOfCommend ContentOfCommend -> ( !_NewLine ~ _Anything ) // _Word can be an executable Command -> !(IllegalStartForCommand) ~ Value IllegalStartForCommand -> ( LogicalChainOperator | PipeOperator | RedirectOperator ) // _Word+ for Multiple Assignments VariableStatement -> VariableName ~ Assignment ~ RightHandExpression VariableName -> *HorizontalNoise ~ _Word ~ (_Colon ~ _TypeIdent)? Variable -> _Word ArrayVariableResolving -> _ArraySigil ~ VariableReference StringVariableResolving -> _StringSigil ~ VariableReference VariableReference -> Variable ~ ( IndexAccess | KeyAccess )? // JustVariableName does not allow index access within a index access. // Correct Example: $var[$another] // Wrong Example: $var[$another[2]] KeyAccess -> _OpenBracets ~ ( _Word | JustVariableName ) ~ _ClosedBracket JustVariableName -> _StringSigil ~ Variable IndexAccess= -> _OpenBrackets ~ SliceAccess ~ _ClosedBracket SliceAccess= -> _Int | ( SliceOperator ~ _Equal? ~ _Int ) // Example: "7.." in "$foo[7..]" SliceOperator= -> _DoublePoint | _TriplePoint Str -> ( _Quotation ~ ( !_SingleQuotation ~ _Anything )* ~ _Quotation ) | ( _SingleQuotation ~ ( !_Quotation ~ _Anything )* ~ _SingleQuotation ) Assignment -> _AddAssignment | _MinusAssignment | _PowerAssignment | _MultAssignment | _InterDivAssignment | _DivAssignment | _ConcatAssignment | _Compare | _Equal BinaryOperators -> _Add | _Subtract | _Power | _Multiply ArrayExpression -> _OpenBrackets ~ ( FirstArrayValue ~ NextArrayValue* ~ noise* )? ~ _ClosedBracket FirstArrayValue -> noise* ~ Value NextArrayValue -> noise+ ~ Value Value -> Str | ProcessExpansion | StringVariableResolving | ArrayVariableResolving | ArrayExpression | FnMethodCall | Number | BraceExpansion | ArithmeticExpansion | WordStartingWithOp | Word | WordStartingWithNumber Word = Number? ~ _Word // Ion shell allows operators at the start of a word like "--p" // It also allows operators on their own like "++" WordStartingWithOp -> ( BinaryOperators | PipeOperator )+ ~ ( Number | _Word )? // ( Value | BinaryOperators )* : for multiple values of multiple assignments RightHandExpression -> HorizontalNoise* ~ Value Number -> _Int | _Float Sigil -> _StringSigil | _ArraySigil FnMethodCall -> Sigil ~ _Word ~ OpenParanteseCurlyBracket ~ Value* ~ ClosedParanteseCurlyBracket ProcessExpansion -> StringProcessExpansion | ArrayProcessExpansion StringProcessExpansion -> _StringSigil ~ ProcessExpansionExpression ArrayProcessExpansion -> _ArraySigil ~ ProcessExpansionExpression ProcessExpansionExpression -> OpenParanteseCurlyBracket ~ CommandExpression ~ CloseParanteseCurlyBracket BraceExpansionComponent -> ( BraceExpansion | _Word ) CommaSeparatedWords -> _Word ~ CommaWordComponent* CommaWordComponent -> _Comma ~ BraceExpansionComponent BraceExpansion -> _OpenCurlyBracket ~ ( SliceAccess | CommaSeparatedWords ) ~ _ClosedCurlyBracket BlockStatement -> !_End ~ Statement IfBlock -> IfClause ~ ( !ElseIfClause ~ !_Else ~ BlockStatement)* ~ ElseIfBlock* ~ ElseBlock? ~ _End ElseBlock -> _Else ~ BlockStatement* ElseIfBlock -> ElseIfClause ~ BlockStatement* IfClause -> _If ~ Condition ElseIfClause -> _ElseIf ~ Condition WhileClause -> _While ~ CommandChain WhileBlock -> WhileClause ~ BlockStatement* ~ _End ForBlock -> _For ~ Variable ~ _In ~ Value ~ BlockStatement* ~ _End MatchBlock -> _Match ~ Value ~ CaseBlock+ ~ _End CaseBlock -> CaseCondition ~ (!_Case ~ Statement)* CaseCondition -> _Case ~ Value ~ IfGuard? ~ EndOfStatement IfGuard -> If ~ CommandChain FnBlock -> _Fn ~ _Word ~ ( _WhiteSpace+ ~ Argument )* ~ Statement* ~ _End TypeAnnotation -> _Word ~ ( _Colon ~ CertainType )? CertainType -> ScalarType | ArrayType ScalarType -> _TypeIdent ArrayType -> _OpenSquareBracket ~ ScalarType ~ _CloseSquareBracket ArithmeticExpansion -> _StringSigil ~ _OpenParanteseCurlyBracket ~ _OpenParanteseCurlyBracket ~ MathExpression* ~ _ClosedParanteseCurlyBracket ~ _ClosedParanteseCurlyBracket MathExpression= -> ( NestedMathExpression | MathCalc ) MathValue -> MathValue NestedMathExpression= -> _OpenParanteseCurlyBracket ~ HorizontalNoise* ~ MathEpression ~ HorizontalNoise* ~ _ClosedParanteseCurlyBracket MathCalc -> MathValue ~ ( MathOperator ~ MathValue )? MathOperator -> HorizontalNoise+ ~ _Operator ~ HorizontalNoise+ MathValue= -> _Int | _Float | _Word