Beispiel #1
0
    public static StringLiteral CreatePythonString(string name) {
      StringLiteral term = new StringLiteral(name);
      term.AddStartEnd("'", StringOptions.AllowsAllEscapes);
      term.AddStartEnd("'''", StringOptions.AllowsAllEscapes | StringOptions.AllowsLineBreak);
      term.AddStartEnd("\"", StringOptions.AllowsAllEscapes);
      term.AddStartEnd("\"\"\"", StringOptions.AllowsAllEscapes | StringOptions.AllowsLineBreak);

      term.AddPrefix("u", StringOptions.AllowsAllEscapes);
      term.AddPrefix("r", StringOptions.NoEscapes );
      term.AddPrefix("ur", StringOptions.NoEscapes);
 
      return term;
    }
 public static StringLiteral CreateCSharpString(string name)
 {
     var term = new StringLiteral(name, "\"", StringOptions.AllowsAllEscapes);
     term.AddPrefix("@",
         StringOptions.NoEscapes | StringOptions.AllowsLineBreak | StringOptions.AllowsDoubledQuote);
     return term;
 }
Beispiel #3
0
        public GMacGrammar(GMacGrammarRootType rootType)
        {
            #region Terminals

            var multiLineComment = new CommentTerminal(GMacParseNodeNames.MultiLineComment, "/*", "*/");
            NonGrammarTerminals.Add(multiLineComment);

            var singleLineComment = new CommentTerminal(GMacParseNodeNames.SingleLineComment, "//", "\n", "\r\n");
            NonGrammarTerminals.Add(singleLineComment);

            //Double quoted string
            var dqString = new StringLiteral(GMacParseNodeNames.DqString, "\"", StringOptions.AllowsAllEscapes);
            dqString.AddPrefix("@", StringOptions.NoEscapes | StringOptions.AllowsLineBreak | StringOptions.AllowsDoubledQuote);

            //Single quoted string
            var sqString = new StringLiteral(GMacParseNodeNames.SqString, "'", StringOptions.AllowsAllEscapes);
            sqString.AddPrefix("@", StringOptions.NoEscapes | StringOptions.AllowsLineBreak | StringOptions.AllowsDoubledQuote);

            var identifier = new IdentifierTerminal(GMacParseNodeNames.Identifier);

            var constantNumber = new NumberLiteral(GMacParseNodeNames.ConstantNumber, NumberOptions.AllowSign);

            var punctColon = ToTerm(":");
            var punctDot   = ToTerm(".");
            var punctComma = ToTerm(",");
            var punctEqual = ToTerm("=");
            var punctHash  = ToTerm("#");
            var punctAt    = ToTerm("@");
            var punctAmp   = ToTerm("&");
            var punctLcb   = ToTerm("{");
            var punctRcb   = ToTerm("}");
            var punctLrb   = ToTerm("(");
            var punctRrb   = ToTerm(")");
            var punctLsb   = ToTerm("[");
            var punctRsb   = ToTerm("]");
            var punctLab   = ToTerm("<");
            var punctRab   = ToTerm(">");

            var keywordBreakpoint = ToTerm("breakpoint");

            //TODO: Create an enum for GMacDSL keywords. This is useful for coloring in the source code editor
            var keywordUsing       = ToTerm("using");
            var keywordBegin       = ToTerm("begin");
            var keywordEnd         = ToTerm("end");
            var keywordFrame       = ToTerm("frame");
            var keywordMacro       = ToTerm("macro");
            var keywordTransform   = ToTerm("transform");
            var keywordEuclidean   = ToTerm("euclidean");
            var keywordIpm         = ToTerm("IPM");
            var keywordCbm         = ToTerm("CBM");
            var keywordOrthogonal  = ToTerm("orthogonal");
            var keywordOrthonormal = ToTerm("orthonormal");
            var keywordReciprocal  = ToTerm("reciprocal");
            var keywordClass       = ToTerm("class");
            var keywordGa          = ToTerm("ga");
            var keywordDeclare     = ToTerm("declare");
            var keywordLet         = ToTerm("let");
            var keywordOutput      = ToTerm("output");
            var keywordReturn      = ToTerm("return");
            var keywordNamespace   = ToTerm("namespace");
            var keywordConstant    = ToTerm("constant");
            var keywordStructure   = ToTerm("structure");
            var keywordFrom        = ToTerm("from");
            var keywordTo          = ToTerm("to");
            var keywordOpen        = ToTerm("open");
            var keywordTemplate    = ToTerm("template");
            var keywordImplement   = ToTerm("implement");
            var keywordSubspace    = ToTerm("subspace");
            var keywordOn          = ToTerm("on");
            var keywordAccess      = ToTerm("access");
            var keywordBind        = ToTerm("bind");
            var keywordWith        = ToTerm("with");
            var keywordBinding     = ToTerm("binding");

            var gaOpCaret  = ToTerm("^");
            var gaOpTimes  = ToTerm("*");
            var gaOpDivide = ToTerm("/");
            var gaOpPlus   = ToTerm("+");
            var gaOpMinus  = ToTerm("-");

            var gaOpOuterProduct = ToTerm("op");

            var gaOpGeometricProduct        = ToTerm("gp");
            var gaOpScalarProduct           = ToTerm("sp");
            var gaOpLeftContractionProduct  = ToTerm("lcp");
            var gaOpRightContractionProduct = ToTerm("rcp");
            var gaOpFatDotProduct           = ToTerm("fdp");
            var gaOpHestenesInnrProduct     = ToTerm("hip");
            var gaOpCommutatorProduct       = ToTerm("cp");
            var gaOpAntiCommutatorProduct   = ToTerm("acp");

            var gaOpEuclideanGeometricProduct        = ToTerm("egp");
            var gaOpEuclideanScalarProduct           = ToTerm("esp");
            var gaOpEuclideanLeftContractionProduct  = ToTerm("elcp");
            var gaOpEuclideanRightContractionProduct = ToTerm("ercp");
            var gaOpEuclideanFatDotProduct           = ToTerm("efdp");
            var gaOpEuclideanHestenesInnrProduct     = ToTerm("ehip");
            var gaOpEuclideanCommutatorProduct       = ToTerm("ecp");
            var gaOpEuclideanAntiCommutatorProduct   = ToTerm("eacp");

            #endregion



            #region Non-Terminals

            var gmacDslRoot      = new NonTerminal(GMacParseNodeNames.GMacDslRoot);
            var gmacDslItemsList = new NonTerminal(GMacParseNodeNames.GMacDslItemsList);
            var gmacDslItem      = new NonTerminal(GMacParseNodeNames.GMacDslItem);

            var breakpoint = new NonTerminal(GMacParseNodeNames.Breakpoint);

            var Namespace     = new NonTerminal(GMacParseNodeNames.Namespace);
            var openNamespace = new NonTerminal(GMacParseNodeNames.OpenNamespace);

            var frame                     = new NonTerminal(GMacParseNodeNames.Frame);
            var frameVectors              = new NonTerminal(GMacParseNodeNames.FrameVectors);
            var frameSignature            = new NonTerminal(GMacParseNodeNames.FrameSignature);
            var frameSignatureEuclidean   = new NonTerminal(GMacParseNodeNames.FrameSignatureEuclidean);
            var frameSignatureIpm         = new NonTerminal(GMacParseNodeNames.FrameSignatureIpm);
            var frameSignatureCbm         = new NonTerminal(GMacParseNodeNames.FrameSignatureCbm);
            var frameSignatureOrthonormal = new NonTerminal(GMacParseNodeNames.FrameSignatureOrthonormal);
            var frameSignatureOrthogonal  = new NonTerminal(GMacParseNodeNames.FrameSignatureOrthogonal);
            var frameSignatureReciprocal  = new NonTerminal(GMacParseNodeNames.FrameSignatureReciprocal);

            var frameSubspaceList = new NonTerminal(GMacParseNodeNames.FrameSubspaceList);
            var frameSubspace     = new NonTerminal(GMacParseNodeNames.FrameSubspace);

            var stringLiteral           = new NonTerminal(GMacParseNodeNames.StringLiteral);
            var outerproductList        = new NonTerminal(GMacParseNodeNames.OuterproductList);
            var identifierList          = new NonTerminal(GMacParseNodeNames.IdentifierList);
            var qualifiedIdentifier     = new NonTerminal(GMacParseNodeNames.QualifiedIdentifier);
            var qualifiedIdentifierList = new NonTerminal(GMacParseNodeNames.QualifiedIdentifierList);

            var basisBladesSet               = new NonTerminal(GMacParseNodeNames.BasisBladesSet);
            var basisBladesSetList           = new NonTerminal(GMacParseNodeNames.BasisBladesSetList);
            var basisBladesSetListItem       = new NonTerminal(GMacParseNodeNames.BasisBladesSetListItem);
            var basisBladesSetListItemGaSpan = new NonTerminal(GMacParseNodeNames.BasisBladesSetListItemGaSpan);
            var qualifiedBasisBladesSet      = new NonTerminal(GMacParseNodeNames.QualifiedBasisBladesSet);

            var dataMembersSet          = new NonTerminal(GMacParseNodeNames.DataMembersSet);
            var qualifiedDataMembersSet = new NonTerminal(GMacParseNodeNames.QualifiedDataMembersSet);

            var basisBladeCoefficient          = new NonTerminal(GMacParseNodeNames.BasisBladeCoefficient);
            var qualifiedBasisBladeCoefficient = new NonTerminal(GMacParseNodeNames.QualifiedBasisBladeCoefficient);

            var qualifiedItem = new NonTerminal(GMacParseNodeNames.QualifiedItem);

            var macro                 = new NonTerminal(GMacParseNodeNames.Macro);
            var macroTemplate         = new NonTerminal(GMacParseNodeNames.MacroTemplate);
            var macroInputs           = new NonTerminal(GMacParseNodeNames.MacroInputs);
            var identifierDeclaration = new NonTerminal(GMacParseNodeNames.IdentifierDeclaration);

            var templatesImplementation = new NonTerminal(GMacParseNodeNames.TemplatesImplementation);

            var expressionOpt       = new NonTerminal(GMacParseNodeNames.ExpressionOpt);
            var expression          = new NonTerminal(GMacParseNodeNames.Expression);
            var expressionSum       = new NonTerminal(GMacParseNodeNames.ExpressionSum);
            var expressionProduct   = new NonTerminal(GMacParseNodeNames.ExpressionProduct);
            var expressionAtomic    = new NonTerminal(GMacParseNodeNames.ExpressionAtomic);
            var expressionBracketed = new NonTerminal(GMacParseNodeNames.ExpressionBracketed);
            var expressionScoped    = new NonTerminal(GMacParseNodeNames.ExpressionScoped);

            var expressionFunction = new NonTerminal(GMacParseNodeNames.ExpressionFunction);
            var expressionFunctionDefaultValueOpt          = new NonTerminal(GMacParseNodeNames.ExpressionFunctionDefaultValueOpt);
            var expressionFunctionDefaultValue             = new NonTerminal(GMacParseNodeNames.ExpressionFunctionDefaultValue);
            var expressionFunctionInputsOpt                = new NonTerminal(GMacParseNodeNames.ExpressionFunctionInputsOpt);
            var expressionFunctionInputs                   = new NonTerminal(GMacParseNodeNames.ExpressionFunctionInputs);
            var expressionFunctionInputsExpressions        = new NonTerminal(GMacParseNodeNames.ExpressionFunctionInputsExpressions);
            var expressionFunctionInputsAssignments        = new NonTerminal(GMacParseNodeNames.ExpressionFunctionInputsAssignments);
            var expressionFunctionInputsAssignmentsItem    = new NonTerminal(GMacParseNodeNames.ExpressionFunctionInputsAssignmentsItem);
            var expressionFunctionInputsAssignmentsItemLhs = new NonTerminal(GMacParseNodeNames.ExpressionFunctionInputsAssignmentsItemLhs);

            var expressionComposite = new NonTerminal(GMacParseNodeNames.ExpressionComposite);

            var command        = new NonTerminal(GMacParseNodeNames.Command);
            var commandLet     = new NonTerminal(GMacParseNodeNames.CommandLet);
            var commandLetLhs  = new NonTerminal(GMacParseNodeNames.CommandLetLhs);
            var commandDeclare = new NonTerminal(GMacParseNodeNames.CommandDeclare);
            var commandReturn  = new NonTerminal(GMacParseNodeNames.CommandReturn);
            //var Command_Output = new NonTerminal(GMacParseNodeNames.Command_Output);
            var commandBlock             = new NonTerminal(GMacParseNodeNames.CommandBlock);
            var commandBlockCommandsList = new NonTerminal(GMacParseNodeNames.CommandBlockCommandsList);

            var gaBinarySum      = new NonTerminal(GMacParseNodeNames.GaBinarySum);
            var gaUnaryOperation = new NonTerminal(GMacParseNodeNames.GaUnaryOperation);
            var gaBinaryProduct  = new NonTerminal(GMacParseNodeNames.GaBinaryProduct);


            var constant = new NonTerminal(GMacParseNodeNames.Constant);

            var structure        = new NonTerminal(GMacParseNodeNames.Structure);
            var structureMembers = new NonTerminal(GMacParseNodeNames.StructureMembers);

            var transform = new NonTerminal(GMacParseNodeNames.Transform);

            #endregion



            #region Rules

            switch (rootType)
            {
            case GMacGrammarRootType.Normal:
                Root = gmacDslRoot;
                break;

            case GMacGrammarRootType.Expression:
                Root = expression;
                break;

            case GMacGrammarRootType.QualifiedItem:
                Root = qualifiedItem;
                break;

            case GMacGrammarRootType.Macro:
                Root = macro;
                break;

            case GMacGrammarRootType.Structure:
                Root = structure;
                break;

            case GMacGrammarRootType.Commands:
                Root = commandBlockCommandsList;
                break;

            default:
                Root = gmacDslRoot;
                break;
            }

            gmacDslRoot.Rule =
                gmacDslItemsList;

            gmacDslItemsList.Rule =
                MakeStarRule(gmacDslItemsList, gmacDslItem);

            gmacDslItem.Rule =
                breakpoint
                | Namespace
                | openNamespace
                | frame
                | structure
                | constant
                | macro
                | transform
                | macroTemplate
                | templatesImplementation;


            breakpoint.Rule =
                keywordBreakpoint;


            Namespace.Rule =
                keywordNamespace + qualifiedIdentifier;

            openNamespace.Rule =
                keywordOpen + qualifiedIdentifier;


            frame.Rule =
                keywordFrame + identifier + punctLrb + frameVectors + punctRrb + frameSignature + frameSubspaceList;

            frameVectors.Rule =
                MakePlusRule(frameVectors, punctComma, identifier);

            frameSignature.Rule =
                frameSignatureEuclidean
                | frameSignatureIpm
                | frameSignatureCbm
                | frameSignatureOrthonormal
                | frameSignatureOrthogonal
                | frameSignatureReciprocal;

            frameSignatureEuclidean.Rule =
                keywordEuclidean;

            frameSignatureIpm.Rule =
                keywordIpm + stringLiteral;

            frameSignatureCbm.Rule =
                keywordCbm + qualifiedIdentifier + stringLiteral;

            frameSignatureOrthonormal.Rule =
                keywordOrthonormal + stringLiteral;

            frameSignatureOrthogonal.Rule =
                keywordOrthogonal + stringLiteral;

            frameSignatureReciprocal.Rule =
                keywordReciprocal + qualifiedIdentifier;

            frameSubspaceList.Rule =
                MakeStarRule(frameSubspaceList, frameSubspace);

            frameSubspace.Rule =
                keywordSubspace + identifier + punctEqual + basisBladesSet;


            stringLiteral.Rule =
                dqString | sqString;

            outerproductList.Rule =
                MakePlusRule(outerproductList, gaOpCaret, identifier);

            identifierList.Rule =
                MakePlusRule(identifierList, punctComma, identifier);

            qualifiedIdentifier.Rule =
                MakePlusRule(qualifiedIdentifier, punctDot, identifier);

            qualifiedIdentifierList.Rule =
                MakePlusRule(qualifiedIdentifierList, punctComma, qualifiedIdentifier);


            basisBladesSet.Rule =
                punctAt + basisBladesSetList + punctAt;

            basisBladesSetList.Rule =
                MakePlusRule(basisBladesSetList, punctComma, basisBladesSetListItem);

            basisBladesSetListItem.Rule =
                outerproductList | basisBladesSetListItemGaSpan;

            basisBladesSetListItemGaSpan.Rule =
                keywordGa + punctLcb + identifierList + punctRcb;

            qualifiedBasisBladesSet.Rule =
                qualifiedIdentifier + punctDot + basisBladesSet;


            dataMembersSet.Rule =
                punctAt + identifierList + punctAt;

            qualifiedDataMembersSet.Rule =
                qualifiedIdentifier + punctDot + dataMembersSet;


            basisBladeCoefficient.Rule =
                punctHash + outerproductList + punctHash;

            qualifiedBasisBladeCoefficient.Rule =
                qualifiedIdentifier + punctDot + basisBladeCoefficient;


            qualifiedItem.Rule =
                qualifiedIdentifier
                | qualifiedBasisBladeCoefficient
                | qualifiedBasisBladesSet
                | qualifiedDataMembersSet;//TODO: Implement Qualified_DataMembersSet in the AST generators


            macroTemplate.Rule =
                keywordTemplate + macro;

            macro.Rule =
                keywordMacro + qualifiedIdentifier + punctLrb + macroInputs + punctRrb + punctColon + qualifiedIdentifier + commandBlock;

            macroInputs.Rule =
                MakeStarRule(macroInputs, punctComma, identifierDeclaration);

            identifierDeclaration.Rule =
                identifier + punctColon + qualifiedIdentifier;


            templatesImplementation.Rule =
                keywordImplement + qualifiedIdentifierList + keywordUsing + qualifiedIdentifierList;


            expressionOpt.Rule =
                Empty | expression;

            expression.Rule =
                expressionSum | gaUnaryOperation + expressionSum;

            expressionSum.Rule =
                expressionProduct | expressionSum + gaBinarySum + expressionProduct;

            expressionProduct.Rule =
                expressionAtomic | expressionProduct + gaBinaryProduct + expressionAtomic;

            expressionAtomic.Rule =
                constantNumber
                | qualifiedItem
                | expressionBracketed
                | expressionScoped
                | stringLiteral
                | expressionComposite
                | expressionFunction;

            expressionBracketed.Rule =
                punctLrb + expression + punctRrb;

            expressionScoped.Rule =
                qualifiedIdentifier + punctDot + punctAmp + expression + punctAmp;


            expressionFunction.Rule =
                qualifiedIdentifier + expressionFunctionDefaultValueOpt + punctLrb + expressionFunctionInputsOpt + punctRrb;

            expressionFunctionDefaultValueOpt.Rule =
                expressionFunctionDefaultValue | Empty;

            expressionFunctionDefaultValue.Rule =
                punctLcb + expression + punctRcb;

            expressionFunctionInputsOpt.Rule =
                Empty | expressionFunctionInputs;

            expressionFunctionInputs.Rule =
                expressionFunctionInputsExpressions | expressionFunctionInputsAssignments;

            expressionFunctionInputsExpressions.Rule =
                MakePlusRule(expressionFunctionInputsExpressions, punctComma, expression);

            expressionFunctionInputsAssignments.Rule =
                MakePlusRule(expressionFunctionInputsAssignments, punctComma, expressionFunctionInputsAssignmentsItem);

            expressionFunctionInputsAssignmentsItem.Rule =
                expressionFunctionInputsAssignmentsItemLhs + punctEqual + expression;

            expressionFunctionInputsAssignmentsItemLhs.Rule =
                qualifiedIdentifier | qualifiedBasisBladeCoefficient | basisBladeCoefficient;


            expressionComposite.Rule =
                punctLcb + keywordOutput + identifierDeclaration + commandBlockCommandsList + punctRcb;


            commandBlock.Rule =
                keywordBegin + commandBlockCommandsList + keywordEnd;

            commandBlockCommandsList.Rule =
                MakePlusRule(commandBlockCommandsList, command);

            command.Rule =
                commandDeclare
                | commandLet
                | commandReturn
                | commandBlock;
            //| Command_Output


            commandLet.Rule =
                keywordLet + commandLetLhs + punctEqual + expression;

            commandLetLhs.Rule =
                identifierDeclaration
                | qualifiedItem;

            commandDeclare.Rule =
                keywordDeclare + identifierDeclaration;

            commandReturn.Rule =
                keywordReturn + expression;


            gaUnaryOperation.Rule =
                gaOpPlus
                | gaOpMinus;

            gaBinarySum.Rule =
                gaOpPlus
                | gaOpMinus;

            gaBinaryProduct.Rule =
                gaOpTimes
                | gaOpDivide
                | gaOpCaret

                | gaOpOuterProduct

                | gaOpGeometricProduct
                | gaOpScalarProduct
                | gaOpLeftContractionProduct
                | gaOpRightContractionProduct
                | gaOpFatDotProduct
                | gaOpHestenesInnrProduct
                | gaOpCommutatorProduct
                | gaOpAntiCommutatorProduct

                | gaOpEuclideanGeometricProduct
                | gaOpEuclideanScalarProduct
                | gaOpEuclideanLeftContractionProduct
                | gaOpEuclideanRightContractionProduct
                | gaOpEuclideanFatDotProduct
                | gaOpEuclideanHestenesInnrProduct
                | gaOpEuclideanCommutatorProduct
                | gaOpEuclideanAntiCommutatorProduct;



            constant.Rule =
                keywordConstant + qualifiedIdentifier + punctEqual + expression;



            structure.Rule =
                keywordStructure + qualifiedIdentifier + punctLrb + structureMembers + punctRrb;

            structureMembers.Rule =
                MakePlusRule(structureMembers, punctComma, identifierDeclaration);



            transform.Rule =
                keywordTransform + identifier + keywordFrom + qualifiedIdentifier + keywordTo + qualifiedIdentifier + punctEqual;



            #endregion

            #region Configuration

            RegisterBracePair("[", "]");
            RegisterBracePair("(", ")");
            RegisterBracePair("{", "}");

            RegisterOperators(1, Associativity.Left,
                              gaOpPlus,
                              gaOpMinus
                              );

            RegisterOperators(2, Associativity.Left,
                              gaOpTimes,
                              gaOpDivide,
                              gaOpCaret,
                              gaOpGeometricProduct,
                              gaOpLeftContractionProduct,
                              gaOpRightContractionProduct,
                              gaOpFatDotProduct,
                              gaOpHestenesInnrProduct,
                              gaOpCommutatorProduct,
                              gaOpAntiCommutatorProduct,
                              gaOpEuclideanGeometricProduct,
                              gaOpEuclideanScalarProduct,
                              gaOpEuclideanLeftContractionProduct,
                              gaOpEuclideanRightContractionProduct,
                              gaOpEuclideanFatDotProduct,
                              gaOpEuclideanHestenesInnrProduct,
                              gaOpEuclideanCommutatorProduct,
                              gaOpEuclideanAntiCommutatorProduct
                              );

            MarkPunctuation(
                keywordBreakpoint,
                keywordUsing,
                keywordBegin,
                keywordEnd,
                keywordDeclare,
                keywordCbm,
                keywordClass,
                keywordConstant,
                keywordEuclidean,
                keywordFrame,
                keywordGa,
                keywordIpm,
                keywordMacro,
                keywordNamespace,
                keywordOrthonormal,
                keywordOrthogonal,
                keywordReciprocal,
                keywordTransform,
                keywordLet,
                keywordOutput,
                keywordReturn,
                keywordStructure,
                keywordFrom,
                keywordTo,
                keywordOpen,
                keywordTemplate,
                keywordImplement,
                keywordSubspace,
                keywordOn,
                keywordAccess,
                keywordBind,
                keywordWith,
                keywordBinding,
                punctColon,
                punctDot,
                punctComma,
                punctEqual,
                punctHash,
                punctAt,
                punctAmp,
                punctLcb,
                punctRcb,
                punctLrb,
                punctRrb,
                punctLsb,
                punctRsb,
                punctLab,
                punctRab
                );

            //this.MarkTransient(
            //    DSL_Definition_Item,
            //    Frame_Classes_List_opt,
            //    Frame_Class_Constants_opt,
            //    Macro_Inputs_opt,
            //    Macro_Input_Type_opt,
            //    Multivector_Expression_Atomic
            //    );

            #endregion
        }
Beispiel #4
0
        public EbisterGrammar() : base(true)
        {
            // 0. Comments
            var commentSingleLine = new CommentTerminal("commentSingleLine", "//", "\r", "\n", "\u2085", "\u2028", "\u2029");
            var commentMultiLine  = new CommentTerminal("commentMultiLine", "/*", "*/");

            NonGrammarTerminals.Add(commentSingleLine);
            NonGrammarTerminals.Add(commentMultiLine);

            // 1. Literals and Operators

            var literalNumber = new NumberLiteral("number",
                                                  NumberOptions.AllowSign |
                                                  NumberOptions.AllowStartEndDot |
                                                  NumberOptions.AllowUnderscore
                                                  );

            literalNumber.AddPrefix("0x", NumberOptions.Hex);
            literalNumber.AddPrefix("0b", NumberOptions.Binary);

            var literalString = new StringLiteral("string", "\"", StringOptions.AllowsAllEscapes);

            literalString.AddPrefix("@", StringOptions.NoEscapes | StringOptions.AllowsLineBreak | StringOptions.AllowsDoubledQuote);

            var identifier = new IdentifierTerminal("identifier");

            var operatorPlus       = ToTerm("+");
            var operatorMinus      = ToTerm("-");
            var operatorAsterisk   = ToTerm("*");
            var operatorSlash      = ToTerm("/");
            var operatorPercent    = ToTerm("%");
            var operatorParenLeft  = ToTerm("(");
            var operatorParenRight = ToTerm(")");
            var operatorSemicolon  = ToTerm(";");

            // 2. Non-Terminals

            // 2.1 Statements
            var program             = new NonTerminal("program", typeof(IronyProgramNode));
            var statement           = new NonTerminal("statement", typeof(IronyGroupedNode));
            var statementBlock      = new NonTerminal("statementBlock", typeof(IronyBlockStatementNode));
            var statementExpression = new NonTerminal("statementBlock", typeof(IronyExpressionStatementNode));
            var statementKeyword    = new NonTerminal("statementKeyword", typeof(IronyKeywordStatementNode));
            var statementRepeat     = new NonTerminal("statementRepeat", typeof(IronyRepeatStatementNode));

            // 2.2 Expressions
            var exprAddSub    = new NonTerminal("exprAddSub", typeof(IronyExpressionNode));
            var exprMulDiv    = new NonTerminal("exprMulDiv", typeof(IronyExpressionNode));
            var expr          = new NonTerminal("expr", typeof(IronyExpressionNode));
            var exprs         = new NonTerminal("exprs", typeof(IronyExpressionsNode));
            var exprParen     = new NonTerminal("exprParen", typeof(IronyParenExpressionNode));
            var exprUnary     = new NonTerminal("exprUnary", typeof(IronyUnaryExpressionNode));
            var exprCall      = new NonTerminal("call", typeof(IronyCallExpressionNode));
            var operatorUnary = new NonTerminal("operatorUnary", typeof(IronyUnaryOperatorNode));

            // 3. BNF Definition
            program.Rule             = MakeStarRule(program, statement);
            exprs.Rule               = MakeStarRule(exprs, ToTerm(","), exprAddSub);
            statementExpression.Rule = exprAddSub + operatorSemicolon;
            statementBlock.Rule      = ToTerm("{") + program + ToTerm("}");
            statementKeyword.Rule    = "break" + operatorSemicolon
                                       | "continue" + operatorSemicolon
                                       | "return" + operatorSemicolon;
            statementRepeat.Rule = "repeat" + statement;
            statement.Rule       = statementExpression
                                   | statementBlock
                                   | statementKeyword
                                   | statementRepeat;
            exprAddSub.Rule = exprMulDiv
                              | exprAddSub + operatorPlus + exprAddSub
                              | exprAddSub + operatorMinus + exprAddSub;
            exprMulDiv.Rule = expr
                              | exprMulDiv + operatorAsterisk + exprMulDiv
                              | exprMulDiv + operatorSlash + exprMulDiv
                              | exprMulDiv + operatorPercent + exprMulDiv;
            exprCall.Rule =
                expr + operatorParenLeft + exprs + operatorParenRight;
            expr.Rule = exprParen
                        | exprUnary
                        | exprCall
                        | literalNumber
                        | literalString
                        | "true"
                        | "false"
                        | "null"
                        | identifier;
            exprParen.Rule     = operatorParenLeft + exprAddSub + operatorParenRight;
            exprUnary.Rule     = operatorUnary + expr;
            operatorUnary.Rule = operatorPlus | operatorMinus;

            Root          = program;
            LanguageFlags = LanguageFlags.CreateAst;
        }
Beispiel #5
0
        public CalcGrammar() : base(true)
        {
            var comment      = new CommentTerminal("comment", "//", "\n", "\r");
            var blockComment = new CommentTerminal("blockComment", "/*", "*/");

            NonGrammarTerminals.Add(comment);
            NonGrammarTerminals.Add(blockComment);

            NonTerminal start                   = new NonTerminal("start", typeof(StatementListNode));
            NonTerminal block                   = new NonTerminal("block");
            NonTerminal instructions            = new NonTerminal("instructions", typeof(BlockNode));
            NonTerminal instruction             = new NonTerminal("instruction");
            NonTerminal embeddedInstruction     = new NonTerminal("embeddedInstruction");
            NonTerminal ifClause                = new NonTerminal("ifClause", typeof(IfNode));
            NonTerminal ifElseClause            = new NonTerminal("ifElseClause", typeof(IfNode));
            NonTerminal forClause               = new NonTerminal("forClause", typeof(ForNode));
            NonTerminal forInitClause           = new NonTerminal("forInit", typeof(StatementListNode));
            NonTerminal forConditionClause      = new NonTerminal("forCondition");
            NonTerminal forIterClause           = new NonTerminal("forIter", typeof(StatementListNode));
            NonTerminal foreachClause           = new NonTerminal("foreachClause", typeof(ForeachNode));
            NonTerminal foreachVarDecl          = new NonTerminal("foreachVarDecl");
            NonTerminal whileClause             = new NonTerminal("whileClause", typeof(WhileNode));
            NonTerminal doWhileClause           = new NonTerminal("doWhileClause", typeof(DoWhileNode));
            NonTerminal returnClause            = new NonTerminal("returnClause", typeof(ReturnNode));
            NonTerminal emptyReturnClause       = new NonTerminal("emptyReturnClause", typeof(ReturnNode));
            NonTerminal breakClause             = new NonTerminal("breakClause", typeof(BreakNode));
            NonTerminal continueClause          = new NonTerminal("continueClause", typeof(ContinueNode));
            NonTerminal usingClause             = new NonTerminal("usingClause", typeof(UsingNode));
            NonTerminal usingNamespace          = new NonTerminal("namespace", typeof(UsingNamespaceNode));
            NonTerminal tryClause               = new NonTerminal("tryClause", typeof(TryNode));
            NonTerminal catchClause             = new NonTerminal("catchClause", typeof(CatchNode));
            NonTerminal finallyClause           = new NonTerminal("finallyClause");
            NonTerminal throwClause             = new NonTerminal("throwClause", typeof(ThrowNode));
            NonTerminal assignment              = new NonTerminal("assignment", typeof(AssignmentNode));
            NonTerminal assignmentOp            = new NonTerminal("assignmentOp", "assignment operator");
            NonTerminal varDeclaration          = new NonTerminal("varDeclaration", typeof(VarDeclarationNode));
            NonTerminal varDeclarationAndAssign = new NonTerminal("varDeclaration", typeof(VarDeclarationNode));
            NonTerminal functionDef             = new NonTerminal("functionDef", typeof(FunctionDefNode));
            NonTerminal functionBody            = new NonTerminal("functionBody", typeof(StatementListNode));
            NonTerminal lambdaBody              = new NonTerminal("lambdaBody", typeof(StatementListNode));
            NonTerminal inlineFunctionDef       = new NonTerminal("inlineFunctionDef", typeof(LambdaNode));
            NonTerminal externFunctionDef       = new NonTerminal("externFunctionDef", typeof(ExternFunctionNode));
            NonTerminal paramList               = new NonTerminal("paramList", typeof(ParamListNode));
            NonTerminal param                   = new NonTerminal("param", typeof(ParamNode));
            NonTerminal lambdaParamList         = new NonTerminal("lambdaParamList", typeof(ParamListNode));
            NonTerminal singleLambdaParamList   = new NonTerminal("lambdaParamList", typeof(ParamListNode));
            NonTerminal lambdaParam             = new NonTerminal("lambdaParam", typeof(ParamNode));
            NonTerminal paramsOrEmpty           = new NonTerminal("paramsOrEmpty");
            NonTerminal arrayDef                = new NonTerminal("arrayDef");
            NonTerminal arrayDefList            = new NonTerminal("arrayDefList", typeof(ArrayDefNode));
            NonTerminal arrayDefListItem        = new NonTerminal("arrayDefListItem");
            NonTerminal namedArrayItem          = new NonTerminal("namedArrayItem", typeof(NamedArrayItemNode));
            NonTerminal expr                   = new NonTerminal("expr");
            NonTerminal prefixExpr             = new NonTerminal("prefixExpr", typeof(IncDecNode));
            NonTerminal postfixExpr            = new NonTerminal("postfixExpr", typeof(IncDecNode));
            NonTerminal binExpr                = new NonTerminal("binExpr", typeof(BinaryOperationNode));
            NonTerminal unExpr                 = new NonTerminal("unExpr", typeof(UnaryExpressionNode));
            NonTerminal var                    = new NonTerminal("var");
            NonTerminal objRef                 = new NonTerminal("objRef");
            NonTerminal memberAccess           = new NonTerminal("memberAccess", typeof(MemberAccessNode));
            NonTerminal ternaryIf              = new NonTerminal("ternaryIf", typeof(IfNode));
            NonTerminal coalescence            = new NonTerminal("coalescence", typeof(CoalescenceNode));
            NonTerminal functionCall           = new NonTerminal("functionCall", typeof(FunctionCallNode));
            NonTerminal varList                = new NonTerminal("varList", typeof(ExpressionListNode));
            NonTerminal array                  = new NonTerminal("array");
            NonTerminal singleDimArray         = new NonTerminal("singleDimArray", typeof(IndexedAccessNode));
            NonTerminal rangeArrayDef          = new NonTerminal("rangeArrayDef", typeof(RangeArrayDefNode));
            NonTerminal rangeInclusiveArrayDef = new NonTerminal("rangeInclusiveArrayDef", typeof(RangeArrayDefNode));
            NonTerminal typeInfo               = new NonTerminal("typeInfo");
            NonTerminal typeInfoOrEmpty        = new NonTerminal("typeInfoOrEmpty");

            IdentifierTerminal name    = new IdentifierTerminal("name", IdOptions.IsNotKeyword);
            IdentifierTerminal newName = new IdentifierTerminal("newName", IdOptions.IsNotKeyword);
            NumberLiteral      number  = new NumberLiteral("number", NumberOptions.AllowUnderscore);

            StringLiteral _string = new StringLiteral("string", "\"", StringOptions.AllowsAllEscapes);

            StringLiteral _char = new StringLiteral("Char", "'", StringOptions.IsChar | StringOptions.AllowsAllEscapes);

            NonTerminal boolVal  = new NonTerminal("boolVal", typeof(BoolValNode));
            NonTerminal nullVal  = new NonTerminal("nullVal", typeof(NullValueNode));
            NonTerminal thisVal  = new NonTerminal("thisVal", typeof(ThisNode));
            NonTerminal binOp    = new NonTerminal("binOp", "operator");
            NonTerminal unaryOp  = new NonTerminal("unaryOp", "operator");
            NonTerminal incDecOp = new NonTerminal("incDecOp", "operator");

            NonTerminal emptyInstruction = new NonTerminal("emptyInstruction", typeof(EmptyNode));

            start.Rule        = MakeStarRule(start, instruction);
            block.Rule        = "{" + instructions + "}";
            instructions.Rule = MakeStarRule(instructions, instruction);
            instruction.Rule  = block
                                | embeddedInstruction + ";"
                                | ifClause
                                | ifElseClause
                                | functionDef
                                | externFunctionDef + ";"
                                | returnClause + ";"
                                | emptyReturnClause
                                | breakClause
                                | continueClause
                                | forClause
                                | foreachClause
                                | whileClause
                                | doWhileClause
                                | usingClause
                                | varDeclaration + ";"
                                | emptyInstruction
                                | tryClause
                                | throwClause + ";";
            emptyInstruction.Rule    = ToTerm(";");
            instruction.ErrorRule    = SyntaxError + ";";
            embeddedInstruction.Rule = functionCall | postfixExpr | prefixExpr | assignment | varDeclarationAndAssign;
            ifElseClause.Rule        = ToTerm("if") + "(" + expr + ")" + instruction
                                       + PreferShiftHere() + "else" + instruction;
            ifClause.Rule           = ToTerm("if") + "(" + expr + ")" + instruction;
            forClause.Rule          = ToTerm("for") + "(" + forInitClause + ";" + forConditionClause + ";" + forIterClause + ")" + instruction;
            forInitClause.Rule      = MakeStarRule(forInitClause, ToTerm(","), embeddedInstruction);
            forConditionClause.Rule = Empty | expr;
            forIterClause.Rule      = MakeStarRule(forIterClause, ToTerm(","), embeddedInstruction);
            foreachClause.Rule      = ToTerm("foreach") + "(" + foreachVarDecl + "in" + expr + ")" + instruction;
            foreachVarDecl.Rule     = varDeclaration | name;
            whileClause.Rule        = ToTerm("while") + "(" + expr + ")" + instruction;
            doWhileClause.Rule      = ToTerm("do") + instruction + ToTerm("while") + "(" + expr + ")" + ToTerm(";");
            returnClause.Rule       = "return" + expr;
            emptyReturnClause.Rule  = ToTerm("return") + ";";
            breakClause.Rule        = ToTerm("break") + ";";
            continueClause.Rule     = ToTerm("continue") + ";";

            tryClause.Rule = "try" + block + (catchClause + finallyClause | finallyClause | catchClause);

            catchClause.Rule   = "catch" + ("(" + name + ")").Q() + block;
            finallyClause.Rule = "finally" + block;

            throwClause.Rule = "throw" + expr;

            usingClause.Rule = ToTerm("using") + usingNamespace + ";";

            usingNamespace.Rule = (name + "." + usingNamespace) | name;

            varDeclaration.Rule          = "var" + name + typeInfoOrEmpty;
            varDeclarationAndAssign.Rule = "var" + name + typeInfoOrEmpty + "=" + expr;

            assignment.Rule   = objRef + assignmentOp + expr;
            assignmentOp.Rule = ToTerm("=") | "+=" | "-=" | "*=" | "/=" | "%=" | "|=" | "^=" | "&=" | "<<=" | ">>=" | "**=";
            objRef.Rule       = name | array | memberAccess;
            memberAccess.Rule = var + PreferShiftHere() + "." + name;

            functionDef.Rule = "function" + name + "(" + paramList + ")" + ToTerm("extension").Q() + functionBody;
            functionDef.NodeCaptionTemplate = "function #{0}(...)";
            inlineFunctionDef.Rule          = (ToTerm("function") + "(" + paramList + ")" + functionBody)
                                              | ("(" + lambdaParamList + ")" + ToTerm("=>") + expr)
                                              | (singleLambdaParamList + "=>" + expr);
            externFunctionDef.Rule = ToTerm("extern") + "function" + name + "(" + paramList + ")" + ToTerm("extension").Q();
            inlineFunctionDef.NodeCaptionTemplate = "function(...)";
            functionBody.Rule = block | returnClause;

            paramList.Rule             = MakeStarRule(paramList, ToTerm(","), param);
            lambdaParamList.Rule       = MakeStarRule(lambdaParamList, ToTerm(","), lambdaParam);
            singleLambdaParamList.Rule = lambdaParam;

            lambdaParam.Rule   = name + ReduceIf("=>", "+", "-", "*", "/", "%", "**", "&", "&&", "|", "||", "^", "==", "<=", ">=", "<", ">", "!=", "<<", ">>", ";", "(", "??");
            param.Rule         = paramsOrEmpty + name + typeInfoOrEmpty;
            paramsOrEmpty.Rule = ToTerm("params") | Empty;

            arrayDef.Rule         = "{" + arrayDefList + "}";
            arrayDefList.Rule     = MakeStarRule(arrayDefList, ToTerm(","), arrayDefListItem);
            arrayDefListItem.Rule = namedArrayItem | expr;
            namedArrayItem.Rule   = (name + ReduceHere() | _string) + "=" + expr;

            rangeArrayDef.Rule = expr + PreferShiftHere() + ".." + expr + ((PreferShiftHere() + ":" + expr) | Empty);

            rangeInclusiveArrayDef.Rule = expr + PreferShiftHere() + "..." + expr + ((PreferShiftHere() + ":" + expr) | Empty);

            expr.Rule = prefixExpr | postfixExpr | ternaryIf
                        | inlineFunctionDef
                        | var | unExpr | binExpr
                        | arrayDef
                        | rangeArrayDef
                        | rangeInclusiveArrayDef
                        | assignment
                        | coalescence;

            coalescence.Rule = expr + "??" + expr;

            binExpr.Rule = expr + binOp + expr;
            binOp.Rule   = ToTerm("&&") | "||" | "&" | "|" | "^"
                           | ToTerm("==") | "<=" | ">=" | "<" | ">" | "!="
                           | ToTerm("+") | "-"
                           | ToTerm("*") | "/" | "%" | "**"
                           | ToTerm("<<") | ">>";
            prefixExpr.Rule  = incDecOp + objRef + ReduceHere();
            postfixExpr.Rule = objRef + PreferShiftHere() + incDecOp;
            unExpr.Rule      = unaryOp + expr + ReduceHere();

            var.Rule = objRef
                       | number
                       | boolVal
                       | nullVal
                       | thisVal
                       | _string
                       | _char
                       | functionCall + ReduceHere()
                       | ("(" + expr + ")");

            ternaryIf.Rule    = expr + "?" + expr + ":" + expr;
            functionCall.Rule = var + PreferShiftHere() + "(" + varList + ")";
            functionCall.NodeCaptionTemplate = "call #{0}(...)";
            varList.Rule = MakeStarRule(varList, ToTerm(","), expr);

            array.Rule          = singleDimArray;
            singleDimArray.Rule = var + PreferShiftHere() + "[" + expr + "]";

            boolVal.Rule = ToTerm("true") | "false";
            nullVal.Rule = ToTerm("null");
            thisVal.Rule = ToTerm("this");

            typeInfoOrEmpty.Rule = ":" + typeInfo | Empty;
            typeInfo.Rule        = ToTerm("string")
                                   | "function"
                                   | "number"
                                   | "bool"
                                   | "table"
                                   | "char";


            unaryOp.Rule  = ToTerm("-") | "!" | "~";
            incDecOp.Rule = ToTerm("++") | "--";

            MarkPunctuation("(", ")", "?", ":", "[", "]", ";", "{", "}", ".", ",", "@", "=>", "??",
                            "return", "if", "else", "for", "while", "break", "continue",
                            "using", "do", "var", "foreach", "in",
                            "try", "catch", "finally", "throw", "extern");
            RegisterBracePair("(", ")");
            RegisterBracePair("[", "]");
            RegisterBracePair("{", "}");

            RegisterOperators(10, "?");
            RegisterOperators(15, "&&", "||", "&", "|", "^");
            RegisterOperators(20, "==", "<", "<=", ">", ">=", "!=");
            RegisterOperators(25, "<<", ">>");
            RegisterOperators(30, "+", "-");
            RegisterOperators(40, "*", "/", "%", "**");
            RegisterOperators(60, "!", "~");
            RegisterOperators(70, "++", "--", "??");
            MarkTransient(var, expr, binOp, unaryOp, block, instruction, embeddedInstruction, objRef, array, arrayDef, assignmentOp, arrayDefListItem, incDecOp, functionBody, lambdaBody, foreachVarDecl, paramsOrEmpty, typeInfoOrEmpty);

            AddTermsReportGroup("assignment", "=", "+=", "-=", "*=", "/=", "%=", "&=", "|=", "^=", "<<=", ">>=");
            AddTermsReportGroup("statement", "if", "while", "for", "return", "break", "continue", "using", "do", "try", "throw", "foreach");
            AddTermsReportGroup("variable declaration", "var");
            AddTermsReportGroup("function declaration", "function", "extern");
            AddTermsReportGroup("constant", number, _string, _char);
            AddTermsReportGroup("constant", "null", "false", "true", "this", "@");
            AddTermsReportGroup("unary operator", "+", "-", "!");
            AddTermsReportGroup("operator", "+", "-", "*", "/", "%", "**", "&", "&&", "|", "||", "^", "?", "==", "<=", "<", ">=", ">", "!=", "<<", ">>", "??", "..");
            AddToNoReportGroup("(", "[", "{", ".", ",", "++", "--");

            MarkReservedWords("if", "else", "return", "function", "while",
                              "for", "null", "false", "true", "this", "break", "continue",
                              "using", "do", "var", "foreach", "in", "params",
                              "try", "catch", "finally", "throw", "extern");

            number.DefaultFloatType = TypeCode.Double;
            number.DefaultIntTypes  = new TypeCode[] { TypeCode.Int64 };
            number.AddPrefix("0x", NumberOptions.Hex);
            number.AddPrefix("0b", NumberOptions.Binary);
            number.AddSuffix("d", TypeCode.Double);
            number.AddSuffix("l", TypeCode.Int64);
            number.AddSuffix("m", TypeCode.Decimal);

            _string.AddPrefix("@", StringOptions.NoEscapes);
            _string.AddPrefix("$", StringOptions.IsTemplate | StringOptions.AllowsAllEscapes);

            var stringTemplateSettings = new StringTemplateSettings();

            stringTemplateSettings.StartTag       = "{";
            stringTemplateSettings.EndTag         = "}";
            stringTemplateSettings.ExpressionRoot = expr;
            this.SnippetRoots.Add(expr);
            _string.AstConfig.NodeType = typeof(StringTemplateNode);
            _string.AstConfig.Data     = stringTemplateSettings;

            this.Root = start;

            this.LanguageFlags = LanguageFlags.CreateAst;
        }
        public TextExpressionDslGrammar()
        {
            #region Terminals

            //Double quoted string
            var dqString = new StringLiteral(TextExpressionDslParseNodeNames.DqString, "\"", StringOptions.AllowsAllEscapes);
            dqString.AddPrefix("@", StringOptions.NoEscapes | StringOptions.AllowsLineBreak | StringOptions.AllowsDoubledQuote);

            //Single quoted string
            var sqString = new StringLiteral(TextExpressionDslParseNodeNames.SqString, "'", StringOptions.AllowsAllEscapes);
            sqString.AddPrefix("@", StringOptions.NoEscapes | StringOptions.AllowsLineBreak | StringOptions.AllowsDoubledQuote);

            var identifier = new IdentifierTerminal(TextExpressionDslParseNodeNames.Identifier);

            var literalNumber = new NumberLiteral(TextExpressionDslParseNodeNames.LiteralNumber, NumberOptions.AllowSign);

            var punctColon = ToTerm(":");
            var punctDot   = ToTerm(".");
            var punctComma = ToTerm(",");
            var punctLsb   = ToTerm("[");
            var punctRsb   = ToTerm("]");
            var punctLcb   = ToTerm("{");
            var punctRcb   = ToTerm("}");

            #endregion

            #region Non-Terminals

            var ntExpression = new NonTerminal(TextExpressionDslParseNodeNames.Expression);

            var ntQualifiedIdentifier = new NonTerminal(TextExpressionDslParseNodeNames.QualifiedIdentifier);

            var ntExpressionName = new NonTerminal(TextExpressionDslParseNodeNames.ExpressionName);

            var ntList = new NonTerminal(TextExpressionDslParseNodeNames.List);

            var ntListArgs = new NonTerminal(TextExpressionDslParseNodeNames.ListArgs);

            var ntDictionary = new NonTerminal(TextExpressionDslParseNodeNames.Dictionary);

            var ntDictionaryArgs = new NonTerminal(TextExpressionDslParseNodeNames.DictionaryArgs);

            var ntDictionaryArg = new NonTerminal(TextExpressionDslParseNodeNames.DictionaryArg);

            #endregion

            #region Rules

            //Set root of grammar
            Root = ntExpression;

            ntExpression.Rule =
                ntQualifiedIdentifier | dqString | sqString | literalNumber | ntList | ntDictionary;

            ntQualifiedIdentifier.Rule =
                MakePlusRule(ntQualifiedIdentifier, punctDot, identifier);

            ntList.Rule =
                ntExpressionName + punctLsb + ntListArgs + punctRsb;

            ntExpressionName.Rule =
                Empty | ntQualifiedIdentifier;

            ntListArgs.Rule =
                MakeStarRule(ntListArgs, punctComma, ntExpression);

            ntDictionary.Rule =
                ntExpressionName + punctLcb + ntDictionaryArgs + punctRcb;

            ntDictionaryArgs.Rule =
                MakeStarRule(ntDictionaryArgs, punctComma, ntDictionaryArg);

            ntDictionaryArg.Rule =
                ntQualifiedIdentifier + punctColon + ntExpression;

            #endregion

            #region Configuration

            RegisterBracePair("[", "]");
            RegisterBracePair("{", "}");

            MarkPunctuation(
                punctColon,
                punctDot,
                punctComma,
                punctLsb,
                punctRsb,
                punctLcb,
                punctRcb
                );

            #endregion
        }