Example #1
0
 /// <summary>
 /// 再帰的に連続させられる一次式の処理
 /// </summary>
 /// <param name="tokens"></param>
 /// <param name="parent"></param>
 /// <returns></returns>
 private KecaknoahPrimaryExpressionAstNode ParsePrimaryRecursiveExpression(Queue<KecaknoahToken> tokens, KecaknoahPrimaryExpressionAstNode parent)
 {
     var result = parent;
     if (!tokens.CheckToken(KecaknoahTokenType.Period, KecaknoahTokenType.ParenStart, KecaknoahTokenType.BracketStart)) return result;
     while (true)
     {
         if (tokens.CheckSkipToken(KecaknoahTokenType.Period))
         {
             result = ParsePrimaryMemberAccessExpression(tokens, result);
         }
         else if (tokens.CheckSkipToken(KecaknoahTokenType.ParenStart))
         {
             result = ParsePrimaryFunctionCallExpression(tokens, result);
         }
         else if (tokens.CheckSkipToken(KecaknoahTokenType.BracketStart))
         {
             result = ParsePrimaryIndexerAccessExpression(tokens, result);
         }
         else
         {
             break;
         }
     }
     return result;
 }
Example #2
0
 /// <summary>
 /// 一次式の処理
 /// </summary>
 /// <param name="tokens"></param>
 /// <returns></returns>
 private KecaknoahPrimaryExpressionAstNode ParsePrimaryExpression(Queue<KecaknoahToken> tokens)
 {
     var factor = ParseFactorExpression(tokens);
     //tokens.SkipLogicalLineBreak();
     var re = ParsePrimaryRecursiveExpression(tokens, factor);
     if (re != factor) return re;
     if (!tokens.CheckToken(KecaknoahTokenType.Increment, KecaknoahTokenType.Decrement)) return factor;
     re = new KecaknoahPrimaryExpressionAstNode();
     re.Target = factor;
     if (tokens.CheckSkipToken(KecaknoahTokenType.Increment)) re.ExpressionType = KecaknoahOperatorType.Increment;
     if (tokens.CheckSkipToken(KecaknoahTokenType.Decrement)) re.ExpressionType = KecaknoahOperatorType.Decrement;
     return re;
 }
Example #3
0
 private KecaknoahForAstNode ParseFor(Queue<KecaknoahToken> tokens, bool single)
 {
     var result = new KecaknoahForAstNode();
     var t = tokens.Peek();
     if (t.Type == KecaknoahTokenType.Identifer)
     {
         tokens.Dequeue();
         result.Name = t.TokenString;
     }
     else
     {
         result.Name = Guid.NewGuid().ToString().Substring(0, 8);
     }
     if (!tokens.CheckSkipToken(KecaknoahTokenType.ParenStart)) throw new KecaknoahParseException(tokens.Dequeue().CreateErrorAt("forの各式は全体をカッコでくくってください。"));
     tokens.SkipLogicalLineBreak();    //TODO: 暗黙改行
     while (true)
     {
         var exp = ParseExpression(tokens);
         result.InitializeExpressions.Add(exp);
         if (tokens.CheckSkipToken(KecaknoahTokenType.Semicolon)) break;
         if (!tokens.CheckSkipToken(KecaknoahTokenType.Comma)) throw new KecaknoahParseException(tokens.Dequeue().CreateErrorAt("初期化式はコンマで区切ってください。"));
         tokens.SkipLogicalLineBreak();    //TODO: 暗黙改行
     }
     tokens.SkipLogicalLineBreak();    //TODO: 暗黙改行
     result.Condition = ParseExpression(tokens);
     if (!tokens.CheckSkipToken(KecaknoahTokenType.Semicolon)) throw new KecaknoahParseException(tokens.Dequeue().CreateErrorAt("セミコロンで区切ってください。"));
     tokens.SkipLogicalLineBreak();    //TODO: 暗黙改行
     while (true)
     {
         var exp = ParseExpression(tokens);
         result.CounterExpressions.Add(exp);
         tokens.SkipLogicalLineBreak();    //TODO: 暗黙改行
         if (tokens.CheckToken(KecaknoahTokenType.ParenEnd)) break;
         if (!tokens.CheckSkipToken(KecaknoahTokenType.Comma)) throw new KecaknoahParseException(tokens.Dequeue().CreateErrorAt("初期化式はコンマで区切ってください。"));
         tokens.SkipLogicalLineBreak();    //TODO: 暗黙改行
     }
     if (!tokens.CheckSkipToken(KecaknoahTokenType.ParenEnd)) throw new KecaknoahParseException(tokens.Dequeue().CreateErrorAt("forの各式は全体をカッコでくくってください。"));
     if (single || !tokens.SkipLogicalLineBreak())
     {
         if (tokens.SkipLogicalLineBreak()) throw new KecaknoahParseException(tokens.Dequeue().CreateErrorAt("単行for文のみ記述できます。"));
         foreach (var i in ParseSingleLineStatement(tokens)) result.AddNode(i);
     }
     else
     {
         foreach (var i in ParseBlock(tokens)) result.AddNode(i);
         if (!tokens.CheckSkipToken(KecaknoahTokenType.NextKeyword)) throw new KecaknoahParseException(tokens.Dequeue().CreateErrorAt("nextで終わっていません。"));
     }
     return result;
 }
Example #4
0
        private KecaknoahExpressionAstNode ParseBinaryExpression(Queue<KecaknoahToken> tokens, int priority)
        {
            if (priority > OperatorMaxPriority) return ParseUnaryExpression(tokens);
            var left = ParseBinaryExpression(tokens, priority + 1);
            var result = new KecaknoahBinaryExpressionAstNode();
            result.FirstNode = left;
            while (true)
            {
                if (tokens.Count == 0) break;
                if (tokens.CheckToken(
                    KecaknoahTokenType.ParenEnd, KecaknoahTokenType.Comma, KecaknoahTokenType.BracketEnd,
                    KecaknoahTokenType.ThenKeyword, KecaknoahTokenType.ElseKeyword, KecaknoahTokenType.Semicolon,
                    KecaknoahTokenType.NewLine, KecaknoahTokenType.Colon))
                {
                    //tokens.Dequeue();
                    break;
                }
                var nt = tokens.Peek();
                if (OperatorPriorities[nt.Type] != priority) break;
                tokens.Dequeue();
                tokens.SkipLogicalLineBreak();    //TODO: 暗黙改行
                var right = ParseBinaryExpression(tokens, priority + 1);

                result.SecondNode = right;
                result.ExpressionType = OperatorsTokenTable[nt.Type];
                var newres = new KecaknoahBinaryExpressionAstNode();
                newres.FirstNode = result;
                result = newres;
            }
            if (priority == 1)
            {
                var pn = result.FirstNode as KecaknoahBinaryExpressionAstNode;
                if (pn == null) return result.FirstNode;
                while (pn.FirstNode is KecaknoahBinaryExpressionAstNode)
                {
                    switch (pn.ExpressionType)
                    {
                        case KecaknoahOperatorType.Assign:
                        case KecaknoahOperatorType.PlusAssign:
                        case KecaknoahOperatorType.MinusAssign:
                        case KecaknoahOperatorType.MultiplyAssign:
                        case KecaknoahOperatorType.DivideAssign:
                        case KecaknoahOperatorType.AndAssign:
                        case KecaknoahOperatorType.OrAssign:
                        case KecaknoahOperatorType.XorAssign:
                        case KecaknoahOperatorType.ModularAssign:
                        case KecaknoahOperatorType.LeftBitShiftAssign:
                        case KecaknoahOperatorType.RightBitShiftAssign:
                        case KecaknoahOperatorType.NilAssign:
                            break;
                        default:
                            return pn;
                    }
                    var kb = pn.FirstNode as KecaknoahBinaryExpressionAstNode;
                    var nn = new KecaknoahBinaryExpressionAstNode();
                    nn.ExpressionType = pn.ExpressionType;
                    nn.SecondNode = pn.SecondNode;
                    nn.FirstNode = kb.SecondNode;
                    pn.FirstNode = kb.FirstNode;
                    pn.SecondNode = nn;
                }
                return pn;
            }
            return result.FirstNode;
        }
Example #5
0
        private static void ParseFunctionArgumentsList(Queue<KecaknoahToken> tokens, KecaknoahFunctionAstNode result)
        {
            var nt = tokens.Peek();
            switch (nt.Type)
            {
                case KecaknoahTokenType.NewLine:
                case KecaknoahTokenType.Semicolon:
                    break;
                case KecaknoahTokenType.ParenStart:
                    tokens.Dequeue();
                    while (true)
                    {
                        nt = tokens.Dequeue();
                        switch (nt.Type)
                        {
                            case KecaknoahTokenType.Identifer:
                                result.Parameters.Add(nt.TokenString);
                                tokens.CheckSkipToken(KecaknoahTokenType.Comma);
                                break;
                            case KecaknoahTokenType.VariableArguments:
                                result.AllowsVariableArguments = true;
                                if (!tokens.CheckToken(KecaknoahTokenType.ParenEnd)) throw new KecaknoahParseException(nt.CreateErrorAt("可変長引数は最後に配置してください"));
                                break;
                            case KecaknoahTokenType.ParenEnd:
                                goto EndArgsList;
                            default:
                                throw new KecaknoahParseException(nt.CreateErrorAt("仮引数リストに識別子・可変長引数以外を指定しないでください。"));
                        }

                    }
                EndArgsList:;
                    break;
            }
        }