示例#1
0
 public virtual BlockBase StartAlternate(int lineNumber)
 {
     if (Tokens.Last() is ConditionalBlock child)
     {
         child.returnBlockId = this is ConditionalBlock ? returnBlockId : BlockId;
         BlockBase result = child.RequiresAlternate();
         if (result != null)
         {
             result.returnBlockId = this is ConditionalBlock ? returnBlockId : BlockId;
             result = result.StartAlternate(lineNumber);
             (result as ConditionalBlock).AcceptAlternate();
             return(result);
         }
         return(this);
     }
     return(this as ConditionalBlock);
 }
示例#2
0
        public IEnumerator <Script> GetEnumerator()
        {
            bool inScript = false;
            ScriptParserState parserState  = ScriptParserState.None;
            BlockBase         currentBlock = null;

            foreach (Token token in tokenizer)
            {
                if (inScript)
                {
                    switch (token.Type)
                    {
                    case TokenType.StatementEnd:
                        currentBlock = currentBlock.CompleteBlock() ?? throw new InvalidDataException($"Malformed Script detected");
                        parserState  = ScriptParserState.None;
                        continue;

                    case TokenType.LineEnd:
                        if (parserState == ScriptParserState.ScriptName)
                        {
                            parserState = ScriptParserState.None;
                        }
                        continue;

                    case TokenType.BlockOpen:
                        currentBlock = currentBlock.StartBlock(tokenizer.LineNumber);
                        continue;

                    case TokenType.BracketOpen:
                        currentBlock = currentBlock.StartEnclosure(tokenizer.LineNumber);
                        continue;

                    case TokenType.BlockClose:
                    case TokenType.BracketClose:
                        if ((token.Type == TokenType.BracketClose && currentBlock is Enclosure) ||
                            (token.Type == TokenType.BlockClose && currentBlock is Block))
                        {
                            currentBlock = currentBlock.CompleteBlock() ?? throw new InvalidDataException($"Malformed Script detected");;
                            continue;
                        }
                        else     //something wrong here
                        {
                            throw new InvalidDataException($"Error in signal script data, matching element not found in line {tokenizer.LineNumber}.");
                        }

                    case TokenType.Value:
                        if (parserState == ScriptParserState.ScriptName)            //script names may include any value token or operator, only ended by line end
                        {
                            (currentBlock as Script).ScriptName += token.Value;
                            continue;
                        }

                        switch (token.Value)
                        {
                        case "REM":
                            yield return(currentBlock as Script);

                            inScript    = false;
                            parserState = ScriptParserState.Remark;
                            continue;

                        case "SCRIPT":
                            if (!(currentBlock is Script))
                            {
                                throw new InvalidDataException($"Error in signal script, matching element not found before new script in line {tokenizer.LineNumber}.");
                            }
                            yield return(currentBlock as Script);

                            if (parserState == ScriptParserState.Remark)
                            {
                                parserState = ScriptParserState.None;
                            }
                            else
                            {
                                currentBlock = new Script(tokenizer.LineNumber);
                                parserState  = ScriptParserState.ScriptName;
                                inScript     = true;
                            }
                            continue;

                        case "IF":
                            currentBlock = currentBlock.StartCondition(tokenizer.LineNumber);
                            continue;

                        case "ELSE":
                            currentBlock = currentBlock.StartAlternate(tokenizer.LineNumber);
                            continue;

                        case "AND":
                        case "OR":
                        case "NOT":
                        case "MOD":
                        case "DIV":
                            currentBlock = currentBlock.Add(new OperatorToken(token.Value, tokenizer.LineNumber), tokenizer.LineNumber);
                            continue;

                        default:
                            currentBlock = currentBlock.Add(new ScriptToken()
                            {
                                Token = token.Value
                            }, tokenizer.LineNumber);
                            continue;
                        }

                    case TokenType.Separator:
                    case TokenType.Tab:
                    case TokenType.Comma:
                        continue;

                    case TokenType.Operator:
                        if (parserState == ScriptParserState.ScriptName)
                        {
                            (currentBlock as Script).ScriptName += token.Value;
                        }
                        else
                        {
                            if (token.Value != "#")     //ignoring single # operator (rounding) which isn't used in OR
                            {
                                currentBlock = currentBlock.Add(new OperatorToken(token.Value, tokenizer.LineNumber), tokenizer.LineNumber);
                            }
                        }
                        continue;

                    default:
                        throw new InvalidOperationException($"Unknown token type {token.Type} containing '{token.Value}' in line {tokenizer.LineNumber}");
                    }
                }
                else if (token.Type == TokenType.Value)
                {
                    switch (token.Value)
                    {
                    case "REM":
                        parserState = ScriptParserState.Remark;
                        continue;

                    case "SCRIPT":
                        if (parserState == ScriptParserState.Remark)
                        {
                            parserState = ScriptParserState.None;
                        }
                        else     // start new script
                        {
                            currentBlock = new Script(tokenizer.LineNumber);
                            parserState  = ScriptParserState.ScriptName;
                            inScript     = true;
                        }
                        continue;
                    }
                }
            }
            yield return(currentBlock as Script);
        }
示例#3
0
 public ConditionalBlock(BlockBase parent, int lineNumber) : base(parent, lineNumber)
 {
 }
示例#4
0
 public Enclosure(BlockBase parent, int lineNumber) : base(parent, lineNumber)
 {
 }
示例#5
0
 public Block(BlockBase parent, int lineNumber) : base(parent, lineNumber)
 {
 }
示例#6
0
 public Statement(BlockBase parent, int lineNumber) : base(parent, lineNumber)
 {
 }
示例#7
0
 protected void AddNestedBlock(BlockBase block)
 {
     Current = block;
     Tokens.Add(block);
 }
示例#8
0
 public BlockBase(BlockBase parent, int lineNumber)
 {
     Parent = parent;
     Parent?.AddNestedBlock(this);
     LineNumber = lineNumber;
 }