Ejemplo n.º 1
0
    public override MatchResult?MatchStep(MatchStack stack, MatchFrame frame, TokenQueue q)
    {
        int idx   = (int)q.Take().Type;
        var match = idx >= 0 && idx < _bitmap.Length && _bitmap[idx];

        return(match ? MatchResult.Matched : MatchResult.NoMatch);
    }
Ejemplo n.º 2
0
    public override MatchResult?MatchStep(MatchStack stack, MatchFrame frame, TokenQueue q)
    {
        switch (q.Take().Type)
        {
        case TokenType.Id:
        case TokenType.Ties:
        case TokenType.Variable when AllowVariable:
            return(MatchResult.Matched);

        default:
            return(MatchResult.NoMatch);
        }
    }
Ejemplo n.º 3
0
 public override MatchResult?MatchStep(MatchStack stack, MatchFrame frame, TokenQueue q)
 {
     if (!frame.ProdMatched)
     {
         if (_prod == null)
         {
             _prod = SqliteGrammar.Prods[ProdName];
         }
         stack.Push(_prod);
         frame.ProdMatched = true;
         return(null);
     }
     else
     {
         return(frame.SubResult);
     }
 }
Ejemplo n.º 4
0
 public override MatchResult?MatchStep(MatchStack stack, MatchFrame frame, TokenQueue q)
 {
     if (frame.OrState == OrTermState.Start)
     {
         // try to match the first sub-production
         stack.Push(Prods[0]);
         frame.OrState     = OrTermState.Match;
         frame.OrProdIndex = 0;
         frame.OrStartLoc  = q.GetLocation();
         return(null);
     }
     else if (frame.OrState == OrTermState.Match)
     {
         // we have finished matching one of the productions.  if it matched, then we're done.  if not, move on
         // to the next production.
         var result = frame.SubResult;
         if (result.IsMatch)
         {
             return(MatchResult.Matched);
         }
         else if (result.ErrorMessage == null)
         {
             // no match.  rewind to the beginning and retry with the next one.
             q.Jump(frame.OrStartLoc);
             frame.OrProdIndex++;
             if (frame.OrProdIndex >= Prods.Length)
             {
                 // we have exhausted all of the possibilities and none of them matched.
                 return(MatchResult.NoMatch);
             }
             stack.Push(Prods[frame.OrProdIndex]);
             return(null);
         }
         else
         {
             // started to match but mismatched past the point of no return.
             return(result);
         }
     }
     else
     {
         throw new Exception($"Unrecognized state: {frame.OrState}");
     }
 }
Ejemplo n.º 5
0
 public override MatchResult?MatchStep(MatchStack stack, MatchFrame frame, TokenQueue q)
 {
     if (frame.OptionalState == OptionalTermState.Start)
     {
         // try to match the sub-production
         stack.Push(Prod);
         frame.OptionalState    = OptionalTermState.Match;
         frame.OptionalStartLoc = q.GetLocation();
         return(null);
     }
     else if (frame.OptionalState == OptionalTermState.Match)
     {
         // done matching the sub-production
         var result = frame.SubResult;
         if (result.IsMatch)
         {
             // the optional term is indeed present.
             return(MatchResult.Matched);
         }
         else if (result.ErrorMessage == null)
         {
             // it didn't match but wasn't an error.  this is fine, but we do have to walk the cursor back to
             // where it started since we effectively "matched" zero tokens.
             q.Jump(frame.OptionalStartLoc);
             return(MatchResult.Matched);
         }
         else
         {
             // it started to match but then mismatched past the point of no return.  that's an error.
             return(result);
         }
     }
     else
     {
         throw new Exception($"Unrecognized state: {frame.OptionalState}");
     }
 }
Ejemplo n.º 6
0
 public override MatchResult?MatchStep(MatchStack stack, MatchFrame frame, TokenQueue q)
 {
     System.Diagnostics.Debugger.Break();
     return(MatchResult.Matched);
 }
Ejemplo n.º 7
0
 public override MatchResult?MatchStep(MatchStack stack, MatchFrame frame, TokenQueue q)
 {
     if (frame.ListState == ListTermState.Start)
     {
         frame.ListState = ListTermState.MatchItem;
         stack.Push(ItemProd);
         return(null); // -> MatchItem
     }
     else if (frame.ListState == ListTermState.MatchSeparator)
     {
         var result = frame.SubResult;
         if (result.IsMatch)
         {
             // we have a separator.  now try to match the item following it.
             frame.ListState = ListTermState.MatchItem;
             stack.Push(ItemProd);
             return(null); // -> MatchItem
         }
         else if (result.ErrorMessage == null)
         {
             // we didn't find a separator.  this list is done.  back up to the beginning of where
             // the not-separator started and we're done.
             q.Jump(frame.ListSeparatorStartLoc);
             if (frame.ListCount < Min)
             {
                 return(MatchResult.Error(
                            $"At least {Min} list item{(Min == 1 ? " is" : "s are")} required, but only " +
                            $"{frame.ListCount} {(frame.ListCount == 1 ? "was" : "were")} provided. " +
                            $"Expected list item: {ItemProd.GetExpected()}"));
             }
             else
             {
                 return(MatchResult.Matched);
             }
         }
         else
         {
             return(result); // error
         }
     }
     else if (frame.ListState == ListTermState.MatchItem)
     {
         var result = frame.SubResult;
         if (result.IsMatch)
         {
             // we have an item.  is there another?
             frame.ListCount++;
             if (SeparatorProd == null)
             {
                 // there is no separator, so match the next item
                 frame.ListState             = ListTermState.MatchItem;
                 frame.ListSeparatorStartLoc = q.GetLocation();
                 stack.Push(ItemProd);
                 return(null); // -> MatchItem
             }
             else
             {
                 // match separator + item
                 frame.ListState             = ListTermState.MatchSeparator;
                 frame.ListSeparatorStartLoc = q.GetLocation();
                 stack.Push(SeparatorProd);
                 return(null); // -> MatchSeparator
             }
         }
         else if (result.ErrorMessage == null)
         {
             if (frame.ListCount == 0)
             {
                 // the first item might be missing because the list can potentially be optional.
                 return(Min == 0 ? MatchResult.Matched : MatchResult.NoMatch);
             }
             else if (SeparatorProd == null)
             {
                 // there's no separator, so eventually we'll end up here when the list ends.
                 q.Jump(frame.ListSeparatorStartLoc);
                 if (frame.ListCount < Min)
                 {
                     return(MatchResult.Error(
                                $"At least {Min} list item{(Min == 1 ? " is" : "s are")} required, but only " +
                                $"{frame.ListCount} {(frame.ListCount == 1 ? "was" : "were")} provided. " +
                                $"Expected list item: {ItemProd.GetExpected()}"));
                 }
                 else
                 {
                     return(MatchResult.Matched);
                 }
             }
             else
             {
                 // subsequent items must be present because, in the MatchItem state, we've already consumed a
                 // separator so there must be an item following it.
                 return(MatchResult.Error($"Expected list item: {ItemProd.GetExpected()}"));
             }
         }
         else
         {
             return(result); // error
         }
     }
     else
     {
         throw new Exception($"Unrecognized state: {frame.ListState}");
     }
 }
Ejemplo n.º 8
0
 public override MatchResult?MatchStep(MatchStack stack, MatchFrame frame, TokenQueue q)
 {
     return(q.Take().Type == TokenType.String ? MatchResult.Matched : MatchResult.NoMatch);
 }
Ejemplo n.º 9
0
 public override MatchResult?MatchStep(MatchStack stack, MatchFrame frame, TokenQueue q)
 {
     return(q.Take().Text.ToLower() == Text.ToLower() ? MatchResult.Matched : MatchResult.NoMatch);
 }
Ejemplo n.º 10
0
 public abstract MatchResult?MatchStep(MatchStack stack, MatchFrame frame, TokenQueue q);
Ejemplo n.º 11
0
        /// <summary>
        /// Decodes text data using a text table
        /// </summary>
        /// <param name="Data">Array of bytes to decode</param>
        /// <param name="Table">Text table</param>
        /// <param name="StartTable">Name of the logical table in the text table to start with</param>
        /// <returns></returns>
        public static string UsingTable(byte[] Data, Table Table, string StartTable = "{main}", bool ShowAddr = false, uint StartOffset = 0)
        {
            var _out = new StringBuilder();
            byte[] testseq;

            var TableStack = new Stack<MatchFrame>();     // tracks which tables have been switched from
            MatchFrame thisframe = new MatchFrame(Table.LogicalTables[StartTable],0);
            bool matched;

            int testloop; // loop pointer for test sequence
            int remaining = 0;  // bytes remaining in _in array

            // begin loop for all bytes in array passed to this method
            for (int outerloop = 0; outerloop < Data.Length; )
            {
                // reset the match flag
                matched = false;
                // remaining bytes in the data buffer
                remaining = Data.Length - outerloop;

                /*      Search Loop
                 * 1. Make a byte array beginning with the current byte from the for loop
                 * 2. Add x more elements of bytes ahead of current position, where x is the Byte Width (max number of hex digits in logical table)
                 * 3. Check if this byte sequence is in the control code/table switch/end token lists for this logical table
                 * 4. If not, check if this byte sequence is in the dictionary
                 * 5. If not, go back to 1 with using Byte Width - 1
                 * 6. When back down to the original single byte, if it is still not found in the lists of the dict, it is not in the table
                 */

                // increase testloop by the ByteWidth
                // ensure that the length of the testseq does not go past the upper bound of _in
                testloop = thisframe.Table.ByteWidth > remaining ? remaining : thisframe.Table.ByteWidth;

                // Loop for test byte sequence
                for (; testloop > 0; testloop--)
                {
                    // make the testseq as long as testloop and copy that many bytes from _in @ current position (i)
                    testseq = new byte[testloop];
                    Buffer.BlockCopy(Data, outerloop, testseq, 0, testloop);

                    // check to see if this test sequence matches the previous table switch sequence, if the match mode is -1
                    if (thisframe.MatchCount == -1 && thisframe.OrigSeq.SequenceEqual<byte>(testseq))
                    {
                        // then fall back to the previous logical table (match frame)
                        thisframe = TableStack.Pop();
                        outerloop++;
                        break;
                    }

                    // check each of the dictionaries for the test bytes
                    // table switch
                    if (thisframe.Table.TableSwitches.ContainsKey(testseq))
                    {
                        // cache the variable for speed
                        var thisswitch = thisframe.Table.TableSwitches[testseq];
                        TableStack.Push(thisframe);
                        thisframe = new MatchFrame(Table.LogicalTables[thisswitch.TableID], thisswitch.Matches);
                        if (thisframe.MatchCount == -1) thisframe.OrigSeq = testseq;
                        if (thisframe.MatchCount > 0) thisframe.MatchByte = testseq[0];
                        outerloop += testloop;
                        break;
                    }

                    // control code
                    if (thisframe.Table.ControlCodes.ContainsKey(testseq))
                    {
                        // NOTE! It is calling the byte comparer EVERY TIME ControlCodes[testseq] is caleld. cache the variable??
                        // cached variable for speed
                        var thiscode = thisframe.Table.ControlCodes[testseq];
                        if (thiscode.Params == null)
                        {
                            // this control code has no paramaters, so use quick and easy formatting
                            matched = true;
                            _out.Append('[' + thiscode.Label + ']');
                            _out.Append(thiscode.Formatting);
                            outerloop += testloop;
                            break;
                        }
                        else
                        {
                            matched = true;
                            int paramoffset = outerloop + testloop;
                            int paramcount = 0;
                            _out.Append('[' + thiscode.Label);
                            foreach (LogicalTable.ControlCode.Parameter thiscodeparam in thiscode.Params)
                            {
                                switch (thiscodeparam.Type)
                                {
                                    case LogicalTable.ControlCode.Parameter.NumberType.Hex:
                                        _out.Append(' ' + thiscodeparam.Label + "=0x" + Data[paramoffset + paramcount].ToString("X"));
                                        break;
                                    case LogicalTable.ControlCode.Parameter.NumberType.Decimal:
                                        _out.Append(' ' + thiscodeparam.Label + '=' + Data[paramoffset + paramcount].ToString());
                                        break;
                                    case LogicalTable.ControlCode.Parameter.NumberType.Binary:
                                        _out.Append(' ' + thiscodeparam.Label + '=' + Convert.ToString(Data[paramoffset + paramcount], 2));
                                        break;
                                }
                                paramcount++;
                            }

                            _out.Append(']');
                            _out.Append(thiscode.Formatting);
                            outerloop += (testloop + paramcount);
                            break;
                        }
                    }

                    // end token
                    if (thisframe.Table.EndTokens.ContainsKey(testseq))
                    {
                        // cached variable
                        var thistoken = thisframe.Table.EndTokens[testseq];
                        matched = true;
                        _out.Append("[" + thistoken.Label + "]");
                        _out.Append(thistoken.Formatting);
                        if (ShowAddr)
                            _out.AppendLine("[0x" + (StartOffset + outerloop + 1).ToString("X") + "]");
                        outerloop += testloop;
                        break;
                    }

                    // not found among any of the non-standard entries so check standard
                    if (thisframe.Table.StdDict.ContainsKey(testseq))
                    {
                        matched = true;
                        _out.Append(thisframe.Table.StdDict[testseq]);
                        outerloop += testloop;
                        break;
                    }

                    // if we are down to the last iteration (original byte) and still haven't found anything, the byte isn't found
                    if (testloop == 1)
                    {
                        matched = false;
                        if (TableStack.Count > 0 && thisframe.MatchCount == 0) thisframe = TableStack.Pop();
                        else
                        {
                            _out.Append("[" + testseq[0].ToString("X2") + "]");
                            outerloop++;
                        }
                    }
                }
                // end of test loop
                //
                // if there are match frames on the table stack, let's check for a match and act accordingly
                if (TableStack.Count > 0)
                {
                    // matching mode is positive value [with value at 1, the minimum] and there was a match
                    // then return to the previous logical table (matchframe)
                    if (thisframe.MatchCount == 1 && matched)
                        thisframe = TableStack.Pop();
                    // else if matching mode is positive value [with value greater than 1] and there was a match
                    // then decrease the value by 1
                    else if (thisframe.MatchCount > 1 && matched) thisframe.Decrease();
                }
                // didn't find nuthin'!

            }
            return _out.ToString();
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Decodes text data using a text table
        /// </summary>
        /// <param name="Data">Array of bytes to decode</param>
        /// <param name="Table">Text table</param>
        /// <param name="StartTable">Name of the logical table in the text table to start with</param>
        /// <returns></returns>
        public static string UsingTable(byte[] Data, Table Table, string StartTable = "{main}", bool ShowAddr = false, uint StartOffset = 0)
        {
            var _out = new StringBuilder();

            byte[] testseq;

            var        TableStack = new Stack <MatchFrame>(); // tracks which tables have been switched from
            MatchFrame thisframe  = new MatchFrame(Table.LogicalTables[StartTable], 0);
            bool       matched;

            int testloop;      // loop pointer for test sequence
            int remaining = 0; // bytes remaining in _in array

            // begin loop for all bytes in array passed to this method
            for (int outerloop = 0; outerloop < Data.Length;)
            {
                // reset the match flag
                matched = false;
                // remaining bytes in the data buffer
                remaining = Data.Length - outerloop;

                /*      Search Loop
                 * 1. Make a byte array beginning with the current byte from the for loop
                 * 2. Add x more elements of bytes ahead of current position, where x is the Byte Width (max number of hex digits in logical table)
                 * 3. Check if this byte sequence is in the control code/table switch/end token lists for this logical table
                 * 4. If not, check if this byte sequence is in the dictionary
                 * 5. If not, go back to 1 with using Byte Width - 1
                 * 6. When back down to the original single byte, if it is still not found in the lists of the dict, it is not in the table
                 */

                // increase testloop by the ByteWidth
                // ensure that the length of the testseq does not go past the upper bound of _in
                testloop = thisframe.Table.ByteWidth > remaining ? remaining : thisframe.Table.ByteWidth;

                // Loop for test byte sequence
                for (; testloop > 0; testloop--)
                {
                    // make the testseq as long as testloop and copy that many bytes from _in @ current position (i)
                    testseq = new byte[testloop];
                    Buffer.BlockCopy(Data, outerloop, testseq, 0, testloop);

                    // check to see if this test sequence matches the previous table switch sequence, if the match mode is -1
                    if (thisframe.MatchCount == -1 && thisframe.OrigSeq.SequenceEqual <byte>(testseq))
                    {
                        // then fall back to the previous logical table (match frame)
                        thisframe = TableStack.Pop();
                        outerloop++;
                        break;
                    }

                    // check each of the dictionaries for the test bytes
                    // table switch
                    if (thisframe.Table.TableSwitches.ContainsKey(testseq))
                    {
                        // cache the variable for speed
                        var thisswitch = thisframe.Table.TableSwitches[testseq];
                        TableStack.Push(thisframe);
                        thisframe = new MatchFrame(Table.LogicalTables[thisswitch.TableID], thisswitch.Matches);
                        if (thisframe.MatchCount == -1)
                        {
                            thisframe.OrigSeq = testseq;
                        }
                        if (thisframe.MatchCount > 0)
                        {
                            thisframe.MatchByte = testseq[0];
                        }
                        outerloop += testloop;
                        break;
                    }

                    // control code
                    if (thisframe.Table.ControlCodes.ContainsKey(testseq))
                    {
                        // NOTE! It is calling the byte comparer EVERY TIME ControlCodes[testseq] is caleld. cache the variable??
                        // cached variable for speed
                        var thiscode = thisframe.Table.ControlCodes[testseq];
                        if (thiscode.Params == null)
                        {
                            // this control code has no paramaters, so use quick and easy formatting
                            matched = true;
                            _out.Append('[' + thiscode.Label + ']');
                            _out.Append(thiscode.Formatting);
                            outerloop += testloop;
                            break;
                        }
                        else
                        {
                            matched = true;
                            int paramoffset = outerloop + testloop;
                            int paramcount  = 0;
                            _out.Append('[' + thiscode.Label);
                            foreach (LogicalTable.ControlCode.Parameter thiscodeparam in thiscode.Params)
                            {
                                switch (thiscodeparam.Type)
                                {
                                case LogicalTable.ControlCode.Parameter.NumberType.Hex:
                                    _out.Append(' ' + thiscodeparam.Label + "=0x" + Data[paramoffset + paramcount].ToString("X"));
                                    break;

                                case LogicalTable.ControlCode.Parameter.NumberType.Decimal:
                                    _out.Append(' ' + thiscodeparam.Label + '=' + Data[paramoffset + paramcount].ToString());
                                    break;

                                case LogicalTable.ControlCode.Parameter.NumberType.Binary:
                                    _out.Append(' ' + thiscodeparam.Label + '=' + Convert.ToString(Data[paramoffset + paramcount], 2));
                                    break;
                                }
                                paramcount++;
                            }

                            _out.Append(']');
                            _out.Append(thiscode.Formatting);
                            outerloop += (testloop + paramcount);
                            break;
                        }
                    }

                    // end token
                    if (thisframe.Table.EndTokens.ContainsKey(testseq))
                    {
                        // cached variable
                        var thistoken = thisframe.Table.EndTokens[testseq];
                        matched = true;
                        _out.Append("[" + thistoken.Label + "]");
                        _out.Append(thistoken.Formatting);
                        if (ShowAddr)
                        {
                            _out.AppendLine("[0x" + (StartOffset + outerloop + 1).ToString("X") + "]");
                        }
                        outerloop += testloop;
                        break;
                    }

                    // not found among any of the non-standard entries so check standard
                    if (thisframe.Table.StdDict.ContainsKey(testseq))
                    {
                        matched = true;
                        _out.Append(thisframe.Table.StdDict[testseq]);
                        outerloop += testloop;
                        break;
                    }

                    // if we are down to the last iteration (original byte) and still haven't found anything, the byte isn't found
                    if (testloop == 1)
                    {
                        matched = false;
                        if (TableStack.Count > 0 && thisframe.MatchCount == 0)
                        {
                            thisframe = TableStack.Pop();
                        }
                        else
                        {
                            _out.Append("[" + testseq[0].ToString("X2") + "]");
                            outerloop++;
                        }
                    }
                }
                // end of test loop
                //
                // if there are match frames on the table stack, let's check for a match and act accordingly
                if (TableStack.Count > 0)
                {
                    // matching mode is positive value [with value at 1, the minimum] and there was a match
                    // then return to the previous logical table (matchframe)
                    if (thisframe.MatchCount == 1 && matched)
                    {
                        thisframe = TableStack.Pop();
                    }
                    // else if matching mode is positive value [with value greater than 1] and there was a match
                    // then decrease the value by 1
                    else if (thisframe.MatchCount > 1 && matched)
                    {
                        thisframe.Decrease();
                    }
                }
                // didn't find nuthin'!
            }
            return(_out.ToString());
        }