示例#1
0
		private PPNode ParsePreprocessorDirective()							
		{
			PPNode result = null;
			int startLine = lineCount;

			inPPDirective = true;
			Advance(); // over hash

            IdentifierExpression ie = (IdentifierExpression)ParseIdentifierOrKeyword(false, false, false, false);
			string ppKind = ie.Identifier;

			PreprocessorID id = PreprocessorID.Empty;
			if (preprocessor.ContainsKey(ppKind))
			{
				id = preprocessor[ppKind];
			}
			else
			{
				ReportError("Preprocessor directive must be valid identifier, rather than \"" + ppKind + "\".");
			}

			switch (id)
			{
				case PreprocessorID.Define:
					// conditional-symbol pp-newline
                    IdentifierExpression def = (IdentifierExpression)ParseIdentifierOrKeyword(false, false, false, false);
					if (!ppDefs.ContainsKey(def.Identifier))
					{
						ppDefs.Add(def.Identifier, PreprocessorID.Empty);
					}
					result = new PPDefineNode(def );
					break;
				case PreprocessorID.Undef:
					// conditional-symbol pp-newline
                    IdentifierExpression undef = (IdentifierExpression)ParseIdentifierOrKeyword(false, false, false, false);
					if(ppDefs.ContainsKey(undef.Identifier))
					{
						ppDefs.Remove(undef.Identifier);
					}
					result = new PPDefineNode(undef );
					break;
				case PreprocessorID.If:
					// pp-expression pp-newline conditional-section(opt)
					if (curtok.ID == TokenID.LParen)
					{
						Advance();
					}
					//int startCount = lineCount;
					ppCondition = false;
					
					// todo: account for true, false, ||, &&, ==, !=, ! 
                    //IdentifierExpression ifexpr = (IdentifierExpression)ParseIdentifierOrKeyword(false, false, false, false);
                    ExpressionNode ifexpr = ParseExpression(true);

                    // TODO : Parse and interpret identifier : mono file test-345.cs -> #if (!TEST && !DUNNO && !DUNNO)

					if ( (ifexpr is IdentifierExpression)
                            && ppDefs.ContainsKey(((IdentifierExpression)ifexpr).Identifier))
					{
						ppCondition = true;
					}
					//result = new PPIfNode(ParseExpressionToNewline());
					if (curtok.ID == TokenID.RParen)
					{
						Advance();
					}
					if (ppCondition == false)
					{
						// skip this block
						SkipToElseOrEndIf();
					}
					break;
				case PreprocessorID.Elif:
					// pp-expression pp-newline conditional-section(opt)
					SkipToEOL(startLine);
					break;
				case PreprocessorID.Else:
					// pp-newline conditional-section(opt)
					if (ppCondition)
					{
						// skip this block
						SkipToElseOrEndIf();
					}
					break;
				case PreprocessorID.Endif:
					// pp-newline
					result = new PPEndIfNode(curtok);
					ppCondition = false;
					break;
				case PreprocessorID.Line:
					// line-indicator pp-newline
					SkipToEOL(startLine);
					break;
				case PreprocessorID.Error:
					// pp-message
					SkipToEOL(startLine);
					break;
				case PreprocessorID.Warning:
					// pp-message
					SkipToEOL(startLine);
					break;
				case PreprocessorID.Region:
					// pp-message
					SkipToEOL(startLine);
					break;
				case PreprocessorID.Endregion:
					// pp-message
					SkipToEOL(startLine);
					break;
				case PreprocessorID.Pragma:
					// pp-message
                    //pragma-warning-body:
                    //  warning   whitespace   warning-action
                    //  warning   whitespace   warning-action   whitespace   warning-list
                    int start_line = curtok.Line;

                    result = new PPPragmaNode(curtok);

                    if (curtok.Line == start_line)
                    {
                        ((PPPragmaNode)result).Identifier = (IdentifierExpression)ParseIdentifierOrKeyword(false, false, false, false);
                    }

                    if (curtok.Line == start_line)
                    {
                        string paction = ((IdentifierExpression)ParseIdentifierOrKeyword(false, false, false, false)).Identifier;
                        ((PPPragmaNode)result).Action = (PragmaAction)Enum.Parse(typeof(PragmaAction), paction);
                    }

                    while (curtok.Line == start_line)
                    {
                        if (curtok.ID != TokenID.Comma)
                        {
                            if (curtok.ID == TokenID.IntLiteral)
                            {
                                ((PPPragmaNode)result).Value.Add(new ConstantExpression(new IntegralPrimitive(strings[curtok.Data], IntegralType.Int, curtok) ));
                            }
                            else
                            {
                                if (curtok.ID == TokenID.UIntLiteral)
                                {
                                    ((PPPragmaNode)result).Value.Add(new ConstantExpression(new IntegralPrimitive(strings[curtok.Data], IntegralType.UInt,curtok) ));
                                }
                                else
                                {
                                    if (curtok.ID == TokenID.LongLiteral)
                                    {
                                        ((PPPragmaNode)result).Value.Add(new ConstantExpression(new IntegralPrimitive(strings[curtok.Data], IntegralType.Long, curtok) ));
                                    }
                                    else
                                    {
                                        if (curtok.ID == TokenID.ULongLiteral)
                                        {
                                            ((PPPragmaNode)result).Value.Add(new ConstantExpression(new IntegralPrimitive(strings[curtok.Data], IntegralType.ULong, curtok) ));
                                        }
                                        else
                                        {
                                            RecoverFromError(TokenID.IntLiteral);
                                        }
                                    }
                                }
                            }
                        }

                        Advance();
                    }

                    ppCondition = true;
					break;
				default:
					break;
			}
			inPPDirective = false;
			return result;
		}
示例#2
0
        private PPNode ParsePreprocessorDirective()
        {
            PPNode result = null;
            int startLine = lineCount;

            inPPDirective = true;
            Advance(); // over hash

            IdentifierExpression ie = (IdentifierExpression)ParseIdentifierOrKeyword(false, false, false, false, false);
            string ppKind = ie.Identifier;

            PreprocessorID id = PreprocessorID.Empty;
            if (preprocessor.ContainsKey(ppKind))
            {
                id = preprocessor[ppKind];
            }
            else
            {
                ReportError("Preprocessor directive must be valid identifier, rather than \"" + ppKind + "\".");
            }

            switch (id)
            {
                case PreprocessorID.Define:
                    // conditional-symbol pp-newline
                    if (curtok.ID == TokenID.True || curtok.ID == TokenID.False)
                    {
                        ReportError("Conditional symbol may neither be true nor false");
                        Advance();
                        break;
                    }
                    IdentifierExpression def = (IdentifierExpression)ParseIdentifierOrKeyword(false, false, false, false, false);
                    if (!cu.PPDefs.ContainsKey(def.Identifier))
                    {
                        cu.PPDefs.Add(def.Identifier, PreprocessorID.Empty);
                    }
                    result = new PPDefineNode(def);
                    break;
                case PreprocessorID.Undef:
                    // conditional-symbol pp-newline
                    IdentifierExpression undef = (IdentifierExpression)ParseIdentifierOrKeyword(false, false, false, false, false);
                    if (cu.PPDefs.ContainsKey(undef.Identifier))
                    {
                        cu.PPDefs.Remove(undef.Identifier);
                    }
                    //					result = new PPDefineNode(undef );
                    break;
                case PreprocessorID.If:
                    // pp-expression pp-newline conditional-section(opt)
                    ppCondition = EvalPPExpression(ParsePreprocessorExpression());

                    //result = new PPIfNode(ParseExpressionToNewline());
                    if (!ppCondition)
                    {
                        // skip this block
                        SkipToElseOrEndIf();
                    }
                    break;
                case PreprocessorID.Elif:
                    // pp-expression pp-newline conditional-section(opt)
                    if (ppCondition)   // a previous part was already true?
                    {
                        SkipToElseOrEndIf();
                        break;
                    }

                    ppCondition = EvalPPExpression(ParsePreprocessorExpression());
                    if (!ppCondition)
                    {
                        // skip this block
                        SkipToElseOrEndIf();
                    }
                    break;
                case PreprocessorID.Else:
                    // pp-newline conditional-section(opt)
                    if (ppCondition)
                    {
                        // skip this block
                        SkipToElseOrEndIf();
                    }
                    break;
                case PreprocessorID.Endif:
                    // pp-newline
                    result = new PPEndIfNode(curtok);
                    ppCondition = false;
                    break;
                case PreprocessorID.Line:
                    // line-indicator pp-newline
                    SkipToEOL(startLine);
                    break;
                case PreprocessorID.Error:
                    // pp-message
                    SkipToEOL(startLine);
                    break;
                case PreprocessorID.Warning:
                    // pp-message
                    SkipToEOL(startLine);
                    break;
                case PreprocessorID.Region:
                    // pp-message
                    SkipToEOL(startLine);
                    break;
                case PreprocessorID.Endregion:
                    // pp-message
                    SkipToEOL(startLine);
                    break;
                case PreprocessorID.Pragma:
                    {
                        // pp-message
                        //pragma-warning-body:
                        //  warning   whitespace   warning-action
                        //  warning   whitespace   warning-action   whitespace   warning-list
                        int start_line = curtok.Line;

                        PPPragmaNode pppnode = new PPPragmaNode(curtok);
                        result = pppnode;

                        if (curtok.Line == start_line)
                        {
                            pppnode.Identifier = (IdentifierExpression)ParseIdentifierOrKeyword(false, false, false, false, false);
                        }

                        if (curtok.Line == start_line)
                        {
                            string paction = ((IdentifierExpression)ParseIdentifierOrKeyword(false, false, false, false, false)).Identifier;
                            pppnode.Action = (PragmaAction)Enum.Parse(typeof(PragmaAction), paction);
                        }

                        while (curtok.Line == start_line)
                        {
                            if (curtok.ID != TokenID.Comma)
                            {
                                if (curtok.ID == TokenID.IntLiteral)
                                {
                                    pppnode.Value.Add(new ConstantExpression(new IntegralPrimitive(strings[curtok.Data], IntegralType.Int, curtok)));
                                }
                                else
                                {
                                    if (curtok.ID == TokenID.UIntLiteral)
                                    {
                                        pppnode.Value.Add(new ConstantExpression(new IntegralPrimitive(strings[curtok.Data], IntegralType.UInt, curtok)));
                                    }
                                    else
                                    {
                                        if (curtok.ID == TokenID.LongLiteral)
                                        {
                                            pppnode.Value.Add(new ConstantExpression(new IntegralPrimitive(strings[curtok.Data], IntegralType.Long, curtok)));
                                        }
                                        else
                                        {
                                            if (curtok.ID == TokenID.ULongLiteral)
                                            {
                                                pppnode.Value.Add(new ConstantExpression(new IntegralPrimitive(strings[curtok.Data], IntegralType.ULong, curtok)));
                                            }
                                            else
                                            {
                                                RecoverFromError(TokenID.IntLiteral);
                                            }
                                        }
                                    }
                                }
                            }

                            Advance();
                        }
                        break;
                    }
                default:
                    break;
            }
            inPPDirective = false;
            return result;
        }