Пример #1
0
            internal BnfTerms(TerminalFactoryS TerminalFactoryS)
            {
                this.ADD_OP = TerminalFactoryS.CreateKeyTerm("+", D.BinaryOperator.Add);
                this.SUB_OP = TerminalFactoryS.CreateKeyTerm("-", D.BinaryOperator.Sub);
                this.MUL_OP = TerminalFactoryS.CreateKeyTerm("*", D.BinaryOperator.Mul);
                this.DIV_OP = TerminalFactoryS.CreateKeyTerm("/", D.BinaryOperator.Div);
                this.POW_OP = TerminalFactoryS.CreateKeyTerm("^", D.BinaryOperator.Pow);
                this.MOD_OP = TerminalFactoryS.CreateKeyTerm("%", D.BinaryOperator.Mod);

                this.POS_OP = TerminalFactoryS.CreateKeyTerm("+", D.UnaryOperator.Pos);
                this.NEG_OP = TerminalFactoryS.CreateKeyTerm("-", D.UnaryOperator.Neg);

                this.EQ_OP  = TerminalFactoryS.CreateKeyTerm("==", D.BinaryOperator.Eq);
                this.NEQ_OP = TerminalFactoryS.CreateKeyTerm("<>", D.BinaryOperator.Neq);
                this.LT_OP  = TerminalFactoryS.CreateKeyTerm("<", D.BinaryOperator.Lt);
                this.LTE_OP = TerminalFactoryS.CreateKeyTerm("<=", D.BinaryOperator.Lte);
                this.GT_OP  = TerminalFactoryS.CreateKeyTerm(">", D.BinaryOperator.Gt);
                this.GTE_OP = TerminalFactoryS.CreateKeyTerm(">=", D.BinaryOperator.Gte);

                this.AND_OP = TerminalFactoryS.CreateKeyTerm("&&", D.BinaryOperator.And);
                this.OR_OP  = TerminalFactoryS.CreateKeyTerm("||", D.BinaryOperator.Or);

                this.NOT_OP = TerminalFactoryS.CreateKeyTerm("!", D.UnaryOperator.Not);

                this.QUESTION_MARK_COLON = TerminalFactoryS.CreateKeyTerm("?:");

                this.BOOL_CONSTANT = new BnfiTermConstant <bool>()
                {
                    { "true", true },
                    { "false", false }
                };

                this.LEFT_PAREN  = TerminalFactoryS.CreateKeyTerm("(");
                this.RIGHT_PAREN = TerminalFactoryS.CreateKeyTerm(")");
            }
Пример #2
0
        public GrammarFunction()
            : base(new Domain())
        {
            B = new BnfTerms(new TerminalFactoryS(this));

            this.Root = B.Expression;

            B.Expression.SetRuleOr(
                B.BinaryExpression,
                B.UnaryExpression,
                B.ConditionalTernaryExpression,
                B.NumberLiteral,
                B.BoolLiteral
                );

            B.BinaryExpression.Rule =
                B.BinaryOperator.BindTo(B.BinaryExpression, t => t.Op)
                + B.LEFT_PAREN
                + B.Expression.BindTo(B.BinaryExpression, t => t.Term1)
                + B.COMMA
                + B.Expression.BindTo(B.BinaryExpression, t => t.Term2)
                + B.RIGHT_PAREN
            ;

            B.UnaryExpression.Rule =
                B.UnaryOperator.BindTo(B.UnaryExpression, t => t.Op)
                + B.LEFT_PAREN
                + B.Expression.BindTo(B.UnaryExpression, t => t.Term)
                + B.RIGHT_PAREN
            ;

            B.ConditionalTernaryExpression.Rule =
                B.CONDITIONAL_TERNARY
                + B.LEFT_PAREN
                + B.Expression.BindTo(B.ConditionalTernaryExpression, t => t.Cond)
                + B.COMMA
                + B.Expression.BindTo(B.ConditionalTernaryExpression, t => t.Term1)
                + B.COMMA
                + B.Expression.BindTo(B.ConditionalTernaryExpression, t => t.Term2)
                + B.RIGHT_PAREN
            ;

            var numberLiteralInfo = new NumberLiteralInfo()
                                    .AddPrefix("#b", NumberLiteralBase.Binary)
                                    .AddPrefix("#o", NumberLiteralBase.Octal)
                                    .AddPrefix("#x", NumberLiteralBase.Hexadecimal);

            B.NumberLiteral.Rule = TerminalFactoryS.CreateNumberLiteral <D.NumberLiteral>(numberLiteralInfo);
            B.BoolLiteral.Rule   = B.BOOL_CONSTANT.BindTo(B.BoolLiteral, t => t.Value);

            B.BinaryOperator.Rule = B.ADD_OP | B.SUB_OP | B.MUL_OP | B.DIV_OP | B.POW_OP | B.MOD_OP | B.EQ_OP | B.NEQ_OP | B.LT_OP | B.LTE_OP | B.GT_OP | B.GTE_OP | B.AND_OP | B.OR_OP;
            B.UnaryOperator.Rule  = B.POS_OP | B.NEG_OP | B.NOT_OP;

            RegisterBracePair(B.LEFT_PAREN, B.RIGHT_PAREN);
        }
Пример #3
0
            internal BnfTerms(TerminalFactoryS TerminalFactoryS)
            {
                this.OBJECT_BEGIN = TerminalFactoryS.CreateKeyTerm("{");
                this.OBJECT_END   = TerminalFactoryS.CreateKeyTerm("}");
                this.ARRAY_BEGIN  = TerminalFactoryS.CreateKeyTerm("[");
                this.ARRAY_END    = TerminalFactoryS.CreateKeyTerm("]");
                this.COMMA        = TerminalFactoryS.CreateKeyTerm(",");
                this.COLON        = TerminalFactoryS.CreateKeyTerm(":");
                this.NUMBER       = TerminalFactoryS.CreateNumberLiteral();
                this.STRING       = TerminalFactoryS.CreateStringLiteral(name: "stringliteral", startEndSymbol: "\"");

                this.BOOLEAN = new BnfiTermConstant <bool>()
                {
                    { "true", true },
                    { "false", false }
                };

                this.NULL = new BnfiTermConstantTL()
                {
                    { "null", (object)null }
                };
            }
Пример #4
0
            internal BnfTerms(TerminalFactoryS TerminalFactoryS)
            {
                this.ADD_OP = TerminalFactoryS.CreateKeyTerm("Add", D.BinaryOperator.Add);
                this.SUB_OP = TerminalFactoryS.CreateKeyTerm("Sub", D.BinaryOperator.Sub);
                this.MUL_OP = TerminalFactoryS.CreateKeyTerm("Mul", D.BinaryOperator.Mul);
                this.DIV_OP = TerminalFactoryS.CreateKeyTerm("Div", D.BinaryOperator.Div);
                this.POW_OP = TerminalFactoryS.CreateKeyTerm("Pow", D.BinaryOperator.Pow);
                this.MOD_OP = TerminalFactoryS.CreateKeyTerm("Mod", D.BinaryOperator.Mod);

                this.POS_OP = TerminalFactoryS.CreateKeyTerm("Pos", D.UnaryOperator.Pos);
                this.NEG_OP = TerminalFactoryS.CreateKeyTerm("Neg", D.UnaryOperator.Neg);

                this.EQ_OP  = TerminalFactoryS.CreateKeyTerm("Eq", D.BinaryOperator.Eq);
                this.NEQ_OP = TerminalFactoryS.CreateKeyTerm("Neq", D.BinaryOperator.Neq);
                this.LT_OP  = TerminalFactoryS.CreateKeyTerm("Lt", D.BinaryOperator.Lt);
                this.LTE_OP = TerminalFactoryS.CreateKeyTerm("Lte", D.BinaryOperator.Lte);
                this.GT_OP  = TerminalFactoryS.CreateKeyTerm("Gt", D.BinaryOperator.Gt);
                this.GTE_OP = TerminalFactoryS.CreateKeyTerm("Gte", D.BinaryOperator.Gte);

                this.AND_OP = TerminalFactoryS.CreateKeyTerm("And", D.BinaryOperator.And);
                this.OR_OP  = TerminalFactoryS.CreateKeyTerm("Or", D.BinaryOperator.Or);

                this.NOT_OP = TerminalFactoryS.CreateKeyTerm("Not", D.UnaryOperator.Not);

                this.CONDITIONAL_TERNARY = TerminalFactoryS.CreateKeyTerm("Cond");

                this.COMMA = TerminalFactoryS.CreateKeyTerm(",");

                this.BOOL_CONSTANT = new BnfiTermConstant <bool>()
                {
                    { "true", true },
                    { "false", false }
                };

                this.LEFT_PAREN  = TerminalFactoryS.CreateKeyTerm("(");
                this.RIGHT_PAREN = TerminalFactoryS.CreateKeyTerm(")");
            }
Пример #5
0
            internal BnfTerms(TerminalFactoryS TerminalFactoryS, CultureInfo cultureInfo)
            {
                if (cultureInfo.Name == "hu")
                {
                    this.PROGRAM   = TerminalFactoryS.CreateKeyTerm("program");
                    this.NAMESPACE = TerminalFactoryS.CreateKeyTerm("névtér");
                    this.BEGIN     = TerminalFactoryS.CreateKeyTerm("eleje");
                    this.END       = TerminalFactoryS.CreateKeyTerm("vége");
                    this.FUNCTION  = TerminalFactoryS.CreateKeyTerm("függvény");
                    this.WHILE     = TerminalFactoryS.CreateKeyTerm("amíg");
                    this.FOR       = TerminalFactoryS.CreateKeyTerm("ciklus");
                    this.IF        = TerminalFactoryS.CreateKeyTerm("ha");
                    this.THEN      = TerminalFactoryS.CreateKeyTerm("akkor");
                    this.ELSE      = TerminalFactoryS.CreateKeyTerm("egyébként");
                    this.DO        = TerminalFactoryS.CreateKeyTerm("csináld");
                    this.RETURN    = TerminalFactoryS.CreateKeyTerm("visszatér");
                    this.WRITE     = TerminalFactoryS.CreateKeyTerm("Kiír");
                    this.WRITELN   = TerminalFactoryS.CreateKeyTerm("KiírSor");
                    this.VAR       = TerminalFactoryS.CreateKeyTerm("változó");
                    this.ASYNC     = TerminalFactoryS.CreateKeyTerm("aszink", true);

                    this.AND_OP = TerminalFactoryS.CreateKeyTerm("és", DE.BinaryOperator.And);
                    this.OR_OP  = TerminalFactoryS.CreateKeyTerm("vagy", DE.BinaryOperator.Or);

                    this.NOT_OP = TerminalFactoryS.CreateKeyTerm("nem", DE.UnaryOperator.Not);

                    this.INTEGER_TYPE = TerminalFactoryS.CreateKeyTerm("egész", D.Type.Integer);
                    this.REAL_TYPE    = TerminalFactoryS.CreateKeyTerm("valós", D.Type.Real);
                    this.STRING_TYPE  = TerminalFactoryS.CreateKeyTerm("karakterlánc", D.Type.String);
                    this.CHAR_TYPE    = TerminalFactoryS.CreateKeyTerm("karakter", D.Type.Char);
                    this.BOOL_TYPE    = TerminalFactoryS.CreateKeyTerm("logikai", D.Type.Bool);
                    this.COLOR_TYPE   = TerminalFactoryS.CreateKeyTerm("szín", D.Type.Color);
                    this.DATE_TYPE    = TerminalFactoryS.CreateKeyTerm("dátum", D.Type.Date);

                    this.BOOL_CONSTANT = new BnfiTermConstant <bool>()
                    {
                        { "igaz", true },
                        { "hamis", false }
                    };

                    this.COLOR_CONSTANT = new BnfiTermConstant <D.Color>()
                    {
                        { "szín_fekete", D.Color.Black },
                        { "szín_kék", D.Color.Blue },
                        { "szín_barna", D.Color.Brown },
                        { "szín_szürke", D.Color.Gray },
                        { "szín_zöld", D.Color.Green },
                        { "szín_narancs", D.Color.Orange },
                        { "szín_piros", D.Color.Red },
                        { "szín_fehér", D.Color.White },
                        { "szín_sárga", D.Color.Yellow }
                    };
                }
                else if (cultureInfo.Name == "de")
                {
                    this.PROGRAM   = TerminalFactoryS.CreateKeyTerm("Programm");
                    this.NAMESPACE = TerminalFactoryS.CreateKeyTerm("NameRaum");
                    this.BEGIN     = TerminalFactoryS.CreateKeyTerm("Beginn");
                    this.END       = TerminalFactoryS.CreateKeyTerm("Ende");
                    this.FUNCTION  = TerminalFactoryS.CreateKeyTerm("Funktion");
                    this.WHILE     = TerminalFactoryS.CreateKeyTerm("während");
                    this.FOR       = TerminalFactoryS.CreateKeyTerm("Zyklus");
                    this.IF        = TerminalFactoryS.CreateKeyTerm("wenn");
                    this.THEN      = TerminalFactoryS.CreateKeyTerm("dann");
                    this.ELSE      = TerminalFactoryS.CreateKeyTerm("sonst");
                    this.DO        = TerminalFactoryS.CreateKeyTerm("tun");
                    this.RETURN    = TerminalFactoryS.CreateKeyTerm("zurückholen");
                    this.WRITE     = TerminalFactoryS.CreateKeyTerm("Schreiben");
                    this.WRITELN   = TerminalFactoryS.CreateKeyTerm("SchreibenLeine");
                    this.VAR       = TerminalFactoryS.CreateKeyTerm("Variable");
                    this.ASYNC     = TerminalFactoryS.CreateKeyTerm("async", true);

                    this.AND_OP = TerminalFactoryS.CreateKeyTerm("und", DE.BinaryOperator.And);
                    this.OR_OP  = TerminalFactoryS.CreateKeyTerm("oder", DE.BinaryOperator.Or);

                    this.NOT_OP = TerminalFactoryS.CreateKeyTerm("nicht", DE.UnaryOperator.Not);

                    this.INTEGER_TYPE = TerminalFactoryS.CreateKeyTerm("Ganzzahl", D.Type.Integer);
                    this.REAL_TYPE    = TerminalFactoryS.CreateKeyTerm("ReeleZahl", D.Type.Real);
                    this.STRING_TYPE  = TerminalFactoryS.CreateKeyTerm("Schnur", D.Type.String);
                    this.CHAR_TYPE    = TerminalFactoryS.CreateKeyTerm("Charakter", D.Type.Char);
                    this.BOOL_TYPE    = TerminalFactoryS.CreateKeyTerm("Boolsche", D.Type.Bool);
                    this.COLOR_TYPE   = TerminalFactoryS.CreateKeyTerm("Farbe", D.Type.Color);
                    this.DATE_TYPE    = TerminalFactoryS.CreateKeyTerm("Datum", D.Type.Date);

                    this.BOOL_CONSTANT = new BnfiTermConstant <bool>()
                    {
                        { "richtig", true },
                        { "falsch", false }
                    };

                    this.COLOR_CONSTANT = new BnfiTermConstant <D.Color>()
                    {
                        { "Farbe_schwarz", D.Color.Black },
                        { "Farbe_blau", D.Color.Blue },
                        { "Farbe_braun", D.Color.Brown },
                        { "Farbe_grau", D.Color.Gray },
                        { "Farbe_grün", D.Color.Green },
                        { "Farbe_orange", D.Color.Orange },
                        { "Farbe_rot", D.Color.Red },
                        { "Farbe_weiss", D.Color.White },
                        { "Farbe_gelb", D.Color.Yellow }
                    };
                }
                else
                {
                    this.PROGRAM   = TerminalFactoryS.CreateKeyTerm("program");
                    this.NAMESPACE = TerminalFactoryS.CreateKeyTerm("namespace");
                    this.BEGIN     = TerminalFactoryS.CreateKeyTerm("begin");
                    this.END       = TerminalFactoryS.CreateKeyTerm("end");
                    this.FUNCTION  = TerminalFactoryS.CreateKeyTerm("function");
                    this.WHILE     = TerminalFactoryS.CreateKeyTerm("while");
                    this.FOR       = TerminalFactoryS.CreateKeyTerm("for");
                    this.IF        = TerminalFactoryS.CreateKeyTerm("if");
                    this.THEN      = TerminalFactoryS.CreateKeyTerm("then");
                    this.ELSE      = TerminalFactoryS.CreateKeyTerm("else");
                    this.DO        = TerminalFactoryS.CreateKeyTerm("do");
                    this.RETURN    = TerminalFactoryS.CreateKeyTerm("return");
                    this.WRITE     = TerminalFactoryS.CreateKeyTerm("Write");
                    this.WRITELN   = TerminalFactoryS.CreateKeyTerm("WriteLn");
                    this.VAR       = TerminalFactoryS.CreateKeyTerm("var");
                    this.ASYNC     = TerminalFactoryS.CreateKeyTerm("async", true);

                    this.AND_OP = TerminalFactoryS.CreateKeyTerm("and", DE.BinaryOperator.And);
                    this.OR_OP  = TerminalFactoryS.CreateKeyTerm("or", DE.BinaryOperator.Or);

                    this.NOT_OP = TerminalFactoryS.CreateKeyTerm("not", DE.UnaryOperator.Not);

                    this.INTEGER_TYPE = TerminalFactoryS.CreateKeyTerm("integer", D.Type.Integer);
                    this.REAL_TYPE    = TerminalFactoryS.CreateKeyTerm("real", D.Type.Real);
                    this.STRING_TYPE  = TerminalFactoryS.CreateKeyTerm("string", D.Type.String);
                    this.CHAR_TYPE    = TerminalFactoryS.CreateKeyTerm("char", D.Type.Char);
                    this.BOOL_TYPE    = TerminalFactoryS.CreateKeyTerm("boolean", D.Type.Bool);
                    this.COLOR_TYPE   = TerminalFactoryS.CreateKeyTerm("color", D.Type.Color);
                    this.DATE_TYPE    = TerminalFactoryS.CreateKeyTerm("date", D.Type.Date);

                    this.BOOL_CONSTANT = new BnfiTermConstant <bool>()
                    {
                        { "True", true },
                        { "False", false }
                    };

                    this.COLOR_CONSTANT = new BnfiTermConstant <D.Color>()
                    {
                        { "Color_Black", D.Color.Black },
                        { "Color_Blue", D.Color.Blue },
                        { "Color_Brown", D.Color.Brown },
                        { "Color_Gray", D.Color.Gray },
                        { "Color_Green", D.Color.Green },
                        { "Color_Orange", D.Color.Orange },
                        { "Color_Red", D.Color.Red },
                        { "Color_White", D.Color.White },
                        { "Color_Yellow", D.Color.Yellow }
                    };
                }

                this.DOT           = TerminalFactoryS.CreateKeyTerm(".");
                this.LET           = TerminalFactoryS.CreateKeyTerm(":=");
                this.SEMICOLON     = TerminalFactoryS.CreateKeyTerm(";");
                this.COLON         = TerminalFactoryS.CreateKeyTerm(":");
                this.COMMA         = TerminalFactoryS.CreateKeyTerm(",");
                this.LEFT_PAREN    = TerminalFactoryS.CreateKeyTerm("(");
                this.RIGHT_PAREN   = TerminalFactoryS.CreateKeyTerm(")");
                this.QUESTION_MARK = TerminalFactoryS.CreateKeyTerm("?");

                this.ADD_OP = TerminalFactoryS.CreateKeyTerm("+", DE.BinaryOperator.Add);
                this.SUB_OP = TerminalFactoryS.CreateKeyTerm("-", DE.BinaryOperator.Sub);
                this.MUL_OP = TerminalFactoryS.CreateKeyTerm("*", DE.BinaryOperator.Mul);
                this.DIV_OP = TerminalFactoryS.CreateKeyTerm("/", DE.BinaryOperator.Div);
                this.POW_OP = TerminalFactoryS.CreateKeyTerm("^", DE.BinaryOperator.Pow);
                this.MOD_OP = TerminalFactoryS.CreateKeyTerm("%", DE.BinaryOperator.Mod);

                this.POS_OP = TerminalFactoryS.CreateKeyTerm("+", DE.UnaryOperator.Pos);
                this.NEG_OP = TerminalFactoryS.CreateKeyTerm("-", DE.UnaryOperator.Neg);

                this.EQ_OP  = TerminalFactoryS.CreateKeyTerm("=", DE.BinaryOperator.Eq);
                this.NEQ_OP = TerminalFactoryS.CreateKeyTerm("<>", DE.BinaryOperator.Neq);
                this.LT_OP  = TerminalFactoryS.CreateKeyTerm("<", DE.BinaryOperator.Lt);
                this.LTE_OP = TerminalFactoryS.CreateKeyTerm("<=", DE.BinaryOperator.Lte);
                this.GT_OP  = TerminalFactoryS.CreateKeyTerm(">", DE.BinaryOperator.Gt);
                this.GTE_OP = TerminalFactoryS.CreateKeyTerm(">=", DE.BinaryOperator.Gte);

                // NOTE: to parse keyterms with international characters properly we need to allow international characters in identifiers as well:
                //       CreateCSharpIdentifier creates an identifier terminal that allows internation characters
//                this.IDENTIFIER = TerminalFactoryS.CreateIdentifier();
                this.IDENTIFIER = TerminalFactory.CreateCSharpIdentifier("identifier").IntroIdentifier();
            }
Пример #6
0
        public GrammarP(CultureInfo cultureInfo)
            : base(new Domain())
        {
            B = new BnfTerms(new TerminalFactoryS(this), cultureInfo);

            this.DefaultCulture = cultureInfo;

            this.Root = B.Program;

            B.Program.Rule =
                B.PROGRAM
                + B.Name.BindTo(B.Program, t => t.Name)
                + (B.NAMESPACE + B.NamespaceName).QRef().BindTo(B.Program, t => t.Namespace)
                + B.Function.StarList().BindTo(B.Program, t => t.Functions)
                + B.BEGIN
                + B.Statement.PlusList().BindTo(B.Program, t => t.Body)
                + B.END
                + B.DOT
            ;

            B.Function.Rule =
                B.FUNCTION
                + B.ASYNC.QVal(false).BindTo(B.Function, t => t.IsAsync)
                + B.Name.BindTo(B.Function, t => t.Name)
                + B.LEFT_PAREN
                + B.Parameter.StarList(B.COMMA).BindTo(B.Function, t => t.Parameters)
                + B.RIGHT_PAREN
                + (B.COLON + B.Type).QVal().BindTo(B.Function, t => t.ReturnType)
                + B.BEGIN
                + B.Statement.PlusList().BindTo(B.Function, t => t.Body)
                + B.END
            ;

            B.Parameter.Rule =
                B.VAR
                + B.Name.BindTo(B.Parameter, t => t.Name)
                + B.COLON
                + B.Type.BindTo(B.Parameter, t => t.Type)
            ;

            B.Statement.SetRuleOr(
                B.LocalVariable + B.SEMICOLON,
                B.Assignment + B.SEMICOLON,
                B.While,
                B.For,
                B.If,
#if SEPARATE_IFELSE
                B.IfElse,
#endif
                B.FunctionCall + B.SEMICOLON,
                B.Write + B.SEMICOLON,
                B.WriteLn + B.SEMICOLON,
                B.Return + B.SEMICOLON,
                B.StatementList
                );

            B.Return.Rule =
                B.RETURN
                + B.Expression.BindTo(B.Return, t => t.Value)
            ;

            B.LocalVariable.Rule =
                B.VAR
                + B.Name.BindTo(B.LocalVariable, t => t.Name)
                + B.COLON
                + B.Type.BindTo(B.LocalVariable, t => t.Type)
                + (B.LET + B.Expression).QRef().BindTo(B.LocalVariable, t => t.InitValue)
            ;

            B.Assignment.Rule =
                B.VariableReference.BindTo(B.Assignment, t => t.LValue)
                + B.LET
                + B.Expression.BindTo(B.Assignment, t => t.RValue)
            ;

            B.VariableReference.Rule =
                B.NameRef
                .ConvertValue(_nameRef => ReferenceFactory.Get <D.IVariable>(_nameRef), _variableReference => _variableReference.NameRef)
                .BindTo(B.VariableReference, t => t.Target)
            ;

            B.FunctionReference.Rule =
                B.NameRef.ConvertValue(_nameRef => ReferenceFactory.Get <D.Function>(_nameRef), _functionReference => _functionReference.NameRef)
            ;

            B.StatementList.Rule =
                B.BEGIN
                + B.Statement.PlusList().BindTo(B.StatementList, t => t.Body)
                + B.END
            ;

            B.While.Rule =
                B.WHILE
                + B.LEFT_PAREN
                + B.Expression.BindTo(B.While, t => t.Condition)
                + B.RIGHT_PAREN
                + B.DO
                + B.Statement.BindTo(B.While, t => t.Body)
            ;

            B.For.Rule =
                B.FOR
                + B.LEFT_PAREN
                + B.LocalVariable.StarList(B.COMMA).BindTo(B.For, t => t.Init)
                + B.SEMICOLON
                + B.Expression.BindTo(B.For, t => t.Condition)
                + B.SEMICOLON
                + B.Assignment.StarList(B.COMMA).BindTo(B.For, t => t.Update)
                + B.RIGHT_PAREN
                + B.DO
                + B.Statement.BindTo(B.For, t => t.Body)
            ;

#if SEPARATE_IFELSE
            B.If.Rule =
                B.IF
                + B.LEFT_PAREN
                + B.Expression.BindTo(B.If, t => t.Condition)
                + B.RIGHT_PAREN
                + B.THEN
                + B.Statement.BindTo(B.If, t => t.Body)
            ;

            B.IfElse.Rule =
                B.If.Copy(B.IfElse)
                + B.ELSE
                + B.Statement.BindTo(B.IfElse, t => t.ElseBody)
            ;
#else
            B.If.Rule =
                B.IF
                + B.LEFT_PAREN
                + B.Expression.BindTo(B.If, t => t.Condition)
                + B.RIGHT_PAREN
                + B.THEN
                + B.Statement.BindTo(B.If, t => t.Body)
                + (B.ELSE + B.Statement).QRef().BindTo(B.If, t => t.ElseBody)
            ;
#endif

            B.FunctionCall.Rule =
                B.FunctionReference.BindTo(B.FunctionCall, t => t.FunctionReference)
                + B.LEFT_PAREN
                + B.Argument.StarList(B.COMMA).BindTo(B.FunctionCall, t => t.Arguments)
                + B.RIGHT_PAREN
            ;

            B.Argument.Rule =
                B.Expression.BindTo(B.Argument, t => t.Expression)
            ;

            B.Write.Rule =
                B.WRITE
                + B.LEFT_PAREN
                + B.Expression.StarList(B.COMMA).BindTo(B.Write, t => t.Arguments)
                + B.RIGHT_PAREN
            ;

            B.WriteLn.Rule =
                B.WRITELN
                + B.LEFT_PAREN
                + B.Expression.StarList(B.COMMA).BindTo(B.WriteLn, t => t.Arguments)
                + B.RIGHT_PAREN
            ;

            B.Name.Rule          = B.IDENTIFIER.BindTo(B.Name, t => t.Value);
            B.NameRef.Rule       = B.IDENTIFIER.ConvertValue(_identifier => new NameRef(_identifier), _nameRef => _nameRef.Value);
            B.NamespaceName.Rule =
                B.IDENTIFIER
                .PlusList(B.DOT)
                .ConvertValue(
                    _identifiers => new NameRef(string.Join(B.DOT.Text, _identifiers)),
                    _nameRef => _nameRef.Value.Split(new string[] { B.DOT.Text }, StringSplitOptions.None)
                    );

            B.Expression.SetRuleOr(
                B.BinaryExpression,
                B.UnaryExpression,
                B.ConditionalTernaryExpression,
                B.NumberLiteral,
                B.DateLiteral,
                B.StringLiteral,
                B.BoolLiteral,
                B.ColorLiteral,
                B.FunctionCall,
                B.VariableReference,
                B.LEFT_PAREN + B.Expression + B.RIGHT_PAREN
                );

            B.BinaryExpression.Rule =
                B.Expression.BindTo(B.BinaryExpression, t => t.Term1)
                + B.BinaryOperator.BindTo(B.BinaryExpression, t => t.Op)
                + B.Expression.BindTo(B.BinaryExpression, t => t.Term2)
            ;

            /*
             * NOTE: ImplyPrecedenceHere does not work properly, so we do not use it (it parsed operator NEG as operator POS, and omitted the expression after).
             * So we use ReduceHere instead, which means that unary operators has the highest precedence among operators when used inside a unary expressions.
             * */
            B.UnaryExpression.Rule =
                B.UnaryOperator.BindTo(B.UnaryExpression, t => t.Op)
                + B.Expression.BindTo(B.UnaryExpression, t => t.Term)
                + ReduceHere()      // this is needed for implying precedence (see note above)
            ;

            B.ConditionalTernaryExpression.Rule =
                B.Expression.BindTo(B.ConditionalTernaryExpression, t => t.Cond)
                + B.QUESTION_MARK
                + B.Expression.BindTo(B.ConditionalTernaryExpression, t => t.Term1)
                + B.COLON
                + B.Expression.BindTo(B.ConditionalTernaryExpression, t => t.Term2)
            ;

            var numberLiteralInfo = new NumberLiteralInfo()
                                    .AddSuffix("D", TypeCode.Double)
                                    .AddSuffix("M", TypeCode.Decimal)
                                    .AddPrefix("#b", NumberLiteralBase.Binary)
                                    .AddPrefix("#o", NumberLiteralBase.Octal)
                                    .AddPrefix("#x", NumberLiteralBase.Hexadecimal);

            B.NumberLiteral.Rule = TerminalFactoryS.CreateNumberLiteral <DE.NumberLiteral>(numberLiteralInfo);
//            B.NumberLiteral.Rule = TerminalFactoryS.CreateNumberLiteral().BindTo(B.NumberLiteral, t => t.Value);   // B.NumberLiteral used to be a BnfiTermRecord
            B.StringLiteral.Rule = TerminalFactoryS.CreateStringLiteral(name: "stringliteral", startEndSymbol: "'").BindTo(B.StringLiteral, t => t.Value);
            B.BoolLiteral.Rule   = B.BOOL_CONSTANT.BindTo(B.BoolLiteral, t => t.Value);
            B.ColorLiteral.Rule  = B.COLOR_CONSTANT.BindTo(B.ColorLiteral, t => t.Value);
            B.DateLiteral.Rule   = TerminalFactoryS.CreateDataLiteralDateTimeQuoted(name: "dateliteral", startEndSymbol: "$", dateTimeFormat: D.DateLiteral.Format).BindTo(B.DateLiteral, t => t.Value);

            B.BinaryOperator.Rule = B.ADD_OP | B.SUB_OP | B.MUL_OP | B.DIV_OP | B.POW_OP | B.MOD_OP | B.EQ_OP | B.NEQ_OP | B.LT_OP | B.LTE_OP | B.GT_OP | B.GTE_OP | B.AND_OP | B.OR_OP;
            B.UnaryOperator.Rule  = B.POS_OP | B.NEG_OP | B.NOT_OP;

            B.Type.Rule = B.INTEGER_TYPE | B.REAL_TYPE | B.STRING_TYPE | B.CHAR_TYPE | B.BOOL_TYPE | B.COLOR_TYPE | B.DATE_TYPE;

            /*
             * NOTE: RegisterOperators in Irony is string-based, therefore it is impossible to specify different precedences
             * for binary '+' and unary '+', and for binary '-' and unary '-', so we encode the precedences of unary operators
             * into the grammar by specifying a ReduceHere() hint after unary expressions.
             * */
            RegisterOperators(10, Associativity.Right, B.QUESTION_MARK, B.COLON);
            RegisterOperators(20, B.OR_OP);
            RegisterOperators(30, B.AND_OP);
            RegisterOperators(40, B.EQ_OP, B.NEQ_OP);
            RegisterOperators(50, B.LT_OP, B.LTE_OP, B.GT_OP, B.GTE_OP);
            RegisterOperators(60, B.ADD_OP, B.SUB_OP);
            RegisterOperators(70, B.MUL_OP, B.DIV_OP, B.MOD_OP);
            RegisterOperators(80, Associativity.Right, B.POW_OP);
            RegisterOperators(90, Associativity.Neutral, recurse: false, operators: new[] { B.NEG_OP, B.POS_OP, B.NOT_OP });
            // NOTE: for the parser the unary operators precedences are encoded into the grammar, but for the unparser we have to specify the precedences
            // NOTE: we must not recurse, since NEG_OP and POS_OP has the same terminals as SUB_OP and ADD_OP, respectively ('-' and '+').

            RegisterBracePair(B.LEFT_PAREN, B.RIGHT_PAREN);

            CommentTerminal DelimitedComment  = new CommentTerminal("DelimitedComment", "(@", "@)");
            CommentTerminal SingleLineComment = new CommentTerminal("SingleLineComment", "@@", Environment.NewLine, "\n", "\r");

            NonGrammarTerminals.Add(DelimitedComment);
            NonGrammarTerminals.Add(SingleLineComment);
        }
Пример #7
0
        public GrammarInfix()
            : base(new Domain())
        {
            B = new BnfTerms(new TerminalFactoryS(this));

            this.Root = B.Expression;

            B.Expression.SetRuleOr(
                B.BinaryExpression,
                B.UnaryExpression,
                B.ConditionalTernaryExpression,
                B.NumberLiteral,
                B.BoolLiteral,
                B.LEFT_PAREN + B.Expression + B.RIGHT_PAREN
                );

            B.BinaryExpression.Rule =
                B.Expression.BindTo(B.BinaryExpression, t => t.Term1)
                + B.BinaryOperator.BindTo(B.BinaryExpression, t => t.Op)
                + B.Expression.BindTo(B.BinaryExpression, t => t.Term2)
            ;

            /*
             * NOTE: ImplyPrecedenceHere does not work properly, so we do not use it (it parsed operator NEG as operator POS, and omitted the expression after).
             * So we use ReduceHere instead, which means that unary operators has the highest precedence among operators when used inside a unary expressions.
             * */
            B.UnaryExpression.Rule =
                B.UnaryOperator.BindTo(B.UnaryExpression, t => t.Op)
                + B.Expression.BindTo(B.UnaryExpression, t => t.Term)
                + ReduceHere()      // this is needed for implying precedence (see note above)
            ;

            B.ConditionalTernaryExpression.Rule =
                B.Expression.BindTo(B.ConditionalTernaryExpression, t => t.Cond)
                + B.QUESTION_MARK
                + B.Expression.BindTo(B.ConditionalTernaryExpression, t => t.Term1)
                + B.COLON
                + B.Expression.BindTo(B.ConditionalTernaryExpression, t => t.Term2)
            ;

            var numberLiteralInfo = new NumberLiteralInfo()
                                    .AddPrefix("#b", NumberLiteralBase.Binary)
                                    .AddPrefix("#o", NumberLiteralBase.Octal)
                                    .AddPrefix("#x", NumberLiteralBase.Hexadecimal);

            B.NumberLiteral.Rule = TerminalFactoryS.CreateNumberLiteral <D.NumberLiteral>(numberLiteralInfo);
            B.BoolLiteral.Rule   = B.BOOL_CONSTANT.BindTo(B.BoolLiteral, t => t.Value);

            B.BinaryOperator.Rule = B.ADD_OP | B.SUB_OP | B.MUL_OP | B.DIV_OP | B.POW_OP | B.MOD_OP | B.EQ_OP | B.NEQ_OP | B.LT_OP | B.LTE_OP | B.GT_OP | B.GTE_OP | B.AND_OP | B.OR_OP;
            B.UnaryOperator.Rule  = B.POS_OP | B.NEG_OP | B.NOT_OP;

            /*
             * NOTE: RegisterOperators in Irony is string-based, therefore it is impossible to specify different precedences
             * for binary '+' and unary '+', and for binary '-' and unary '-', so we encode the precedences of unary operators
             * into the grammar by specifying a ReduceHere() hint after unary expressions.
             * */
            RegisterOperators(10, Associativity.Right, B.QUESTION_MARK, B.COLON);
            RegisterOperators(20, B.OR_OP);
            RegisterOperators(30, B.AND_OP);
            RegisterOperators(40, B.EQ_OP, B.NEQ_OP);
            RegisterOperators(50, B.LT_OP, B.LTE_OP, B.GT_OP, B.GTE_OP);
            RegisterOperators(60, B.ADD_OP, B.SUB_OP);
            RegisterOperators(70, B.MUL_OP, B.DIV_OP, B.MOD_OP);
            RegisterOperators(80, Associativity.Right, B.POW_OP);
            RegisterOperators(90, Associativity.Neutral, recurse: false, operators: new[] { B.NEG_OP, B.POS_OP, B.NOT_OP });
            // NOTE: for the parser the unary operators precedences are encoded into the grammar, but for the unparser we have to specify the precedences
            // NOTE: we must not recurse, since NEG_OP and POS_OP has the same terminals as SUB_OP and ADD_OP, respectively ('-' and '+').

            RegisterBracePair(B.LEFT_PAREN, B.RIGHT_PAREN);
        }
Пример #8
0
            internal BnfTerms(TerminalFactoryS TerminalFactoryS)
            {
                this.PROGRAM   = TerminalFactoryS.CreateKeyTerm("program");
                this.NAMESPACE = TerminalFactoryS.CreateKeyTerm("namespace");
                this.BEGIN     = TerminalFactoryS.CreateKeyTerm("{");
                this.END       = TerminalFactoryS.CreateKeyTerm("}");
                this.WHILE     = TerminalFactoryS.CreateKeyTerm("while");
                this.FOR       = TerminalFactoryS.CreateKeyTerm("for");
                this.IF        = TerminalFactoryS.CreateKeyTerm("if");
                this.ELSE      = TerminalFactoryS.CreateKeyTerm("else");
                this.RETURN    = TerminalFactoryS.CreateKeyTerm("return");
                this.WRITE     = TerminalFactoryS.CreateKeyTerm("Write");
                this.WRITELN   = TerminalFactoryS.CreateKeyTerm("WriteLn");
                this.ASYNC     = TerminalFactoryS.CreateKeyTerm("async", true);

                this.DOT           = TerminalFactoryS.CreateKeyTerm(".");
                this.LET           = TerminalFactoryS.CreateKeyTerm("=");
                this.SEMICOLON     = TerminalFactoryS.CreateKeyTerm(";");
                this.COLON         = TerminalFactoryS.CreateKeyTerm(":");
                this.COMMA         = TerminalFactoryS.CreateKeyTerm(",");
                this.LEFT_PAREN    = TerminalFactoryS.CreateKeyTerm("(");
                this.RIGHT_PAREN   = TerminalFactoryS.CreateKeyTerm(")");
                this.QUESTION_MARK = TerminalFactoryS.CreateKeyTerm("?");

                this.ADD_OP = TerminalFactoryS.CreateKeyTerm("+", DE.BinaryOperator.Add);
                this.SUB_OP = TerminalFactoryS.CreateKeyTerm("-", DE.BinaryOperator.Sub);
                this.MUL_OP = TerminalFactoryS.CreateKeyTerm("*", DE.BinaryOperator.Mul);
                this.DIV_OP = TerminalFactoryS.CreateKeyTerm("/", DE.BinaryOperator.Div);
                this.POW_OP = TerminalFactoryS.CreateKeyTerm("^", DE.BinaryOperator.Pow);
                this.MOD_OP = TerminalFactoryS.CreateKeyTerm("%", DE.BinaryOperator.Mod);

                this.POS_OP = TerminalFactoryS.CreateKeyTerm("+", DE.UnaryOperator.Pos);
                this.NEG_OP = TerminalFactoryS.CreateKeyTerm("-", DE.UnaryOperator.Neg);

                this.EQ_OP  = TerminalFactoryS.CreateKeyTerm("==", DE.BinaryOperator.Eq);
                this.NEQ_OP = TerminalFactoryS.CreateKeyTerm("<>", DE.BinaryOperator.Neq);
                this.LT_OP  = TerminalFactoryS.CreateKeyTerm("<", DE.BinaryOperator.Lt);
                this.LTE_OP = TerminalFactoryS.CreateKeyTerm("<=", DE.BinaryOperator.Lte);
                this.GT_OP  = TerminalFactoryS.CreateKeyTerm(">", DE.BinaryOperator.Gt);
                this.GTE_OP = TerminalFactoryS.CreateKeyTerm(">=", DE.BinaryOperator.Gte);

                this.AND_OP = TerminalFactoryS.CreateKeyTerm("&&", DE.BinaryOperator.And);
                this.OR_OP  = TerminalFactoryS.CreateKeyTerm("||", DE.BinaryOperator.Or);

                this.NOT_OP = TerminalFactoryS.CreateKeyTerm("!", DE.UnaryOperator.Not);

                this.INTEGER_TYPE = TerminalFactoryS.CreateKeyTerm("int", D.Type.Integer);
                this.REAL_TYPE    = TerminalFactoryS.CreateKeyTerm("double", D.Type.Real);
                this.STRING_TYPE  = TerminalFactoryS.CreateKeyTerm("string", D.Type.String);
                this.CHAR_TYPE    = TerminalFactoryS.CreateKeyTerm("char", D.Type.Char);
                this.BOOL_TYPE    = TerminalFactoryS.CreateKeyTerm("bool", D.Type.Bool);
                this.COLOR_TYPE   = TerminalFactoryS.CreateKeyTerm("color", D.Type.Color);
                this.DATE_TYPE    = TerminalFactoryS.CreateKeyTerm("date", D.Type.Date);

                this.BOOL_CONSTANT = new BnfiTermConstant <bool>()
                {
                    { "true", true },
                    { "false", false }
                };

                this.COLOR_CONSTANT = new BnfiTermConstant <D.Color>()
                {
                    { "color_black", D.Color.Black },
                    { "color_blue", D.Color.Blue },
                    { "color_brown", D.Color.Brown },
                    { "color_gray", D.Color.Gray },
                    { "color_green", D.Color.Green },
                    { "color_orange", D.Color.Orange },
                    { "color_red", D.Color.Red },
                    { "color_white", D.Color.White },
                    { "color_yellow", D.Color.Yellow }
                };

                // NOTE: to parse keyterms with international characters properly we need to allow international characters in identifiers as well:
                //       CreateCSharpIdentifier creates an identifier terminal that allows internation characters
                //                this.IDENTIFIER = TerminalFactoryS.CreateIdentifier();
                this.IDENTIFIER = TerminalFactory.CreateCSharpIdentifier("identifier").IntroIdentifier();
            }