11 using System.Collections.Generic;
16 namespace Lextm.SharpSnmpLib.Mib
26 : this(file, new StreamReader(file))
30 public Lexer(
string file, TextReader stream)
32 this.Parse(file, stream);
38 return _symbols.GetSymbolEnumerator();
42 #region Parsing of MIB File 44 private class ParseParams
47 public StringBuilder Temp =
new StringBuilder();
48 public bool StringSection =
false;
49 public bool AssignSection =
false;
50 public bool AssignAhead =
false;
51 public bool DotSection =
false;
60 private void Parse(
string file, TextReader stream)
64 throw new ArgumentNullException(
"stream");
67 ParseParams pp =
new ParseParams();
72 while ((line = stream.ReadLine()) != null)
74 if (!pp.StringSection && line.TrimStart().StartsWith(
"--", StringComparison.Ordinal))
80 ParseLine(pp, line, row);
85 private void ParseLine(ParseParams pp,
string line,
int row)
88 int count = line.Length;
89 for (
int i = 0; i < count; i++)
92 bool moveNext = Parse(pp, current, row, i);
100 private bool Parse(ParseParams pp,
char current,
int row,
int column)
114 if (!pp.StringSection)
116 bool moveNext = ParseLastSymbol(pp, row, column);
119 _symbols.Add(CreateSpecialSymbol(pp.File,
'\n', row, column));
123 _symbols.Add(CreateSpecialSymbol(pp.File, current, row, column));
129 pp.StringSection = !pp.StringSection;
134 if ((
int)current == 0x1A)
140 if (Char.IsWhiteSpace(current) && !pp.AssignSection && !pp.StringSection)
142 bool moveNext = ParseLastSymbol(pp, row, column);
145 _symbols.Add(CreateSpecialSymbol(pp.File,
'\n', row, column));
154 pp.AssignAhead =
false;
155 ParseLastSymbol(pp, row, column);
159 if (pp.DotSection && current !=
'.')
161 ParseLastSymbol(pp, row, column);
162 pp.DotSection =
false;
165 if (current ==
'.' && !pp.StringSection)
169 ParseLastSymbol(pp, row, column);
170 pp.DotSection =
true;
174 if (current ==
':' && !pp.StringSection)
176 if (!pp.AssignSection)
178 ParseLastSymbol(pp, row, column);
181 pp.AssignSection =
true;
184 if (current ==
'=' && !pp.StringSection)
186 pp.AssignSection =
false;
187 pp.AssignAhead =
true;
193 pp.Temp.Append(current);
197 private bool ParseLastSymbol(ParseParams pp,
int row,
int column)
199 if (pp.Temp.Length > 0)
201 Symbol s =
new Symbol(pp.File, pp.Temp.ToString(), row, column);
217 private static Symbol CreateSpecialSymbol(
string file,
char value,
int row,
int column)
223 str = Environment.NewLine;
253 throw new ArgumentException(
"value is not a special character");
256 return new Symbol(file, str, row, column);
261 #region Static Parse Helper 265 Symbol current = symbols.NextNonEOLSymbol();
269 return new BitsType(module, name, symbols);
273 return new IntegerType(module, name, current, symbols);
277 return new UnsignedType(module, name, current, symbols);
293 Symbol next = symbols.NextNonEOLSymbol();
304 Symbol next = symbols.NextNonEOLSymbol();
315 Symbol next = symbols.NextNonEOLSymbol();
324 return new Sequence(module, name, symbols);
329 return new Choice(module, name, symbols);
333 return new TypeAssignment(module, name, current, symbols, isMacroSyntax);
341 Symbol current = symbols.NextNonEOLSymbol();
345 StringBuilder longParent =
new StringBuilder();
347 current = symbols.NextNonEOLSymbol();
348 longParent.Append(current);
350 while ((current = symbols.NextNonEOLSymbol()) != null)
356 longParent.Append(current);
358 current = symbols.NextNonEOLSymbol();
359 succeeded = UInt32.TryParse(current.
ToString(), out value);
360 current.Assert(succeeded,
"not a decimal");
361 longParent.Append(current);
362 current = symbols.NextNonEOLSymbol();
364 longParent.Append(current);
370 parent = longParent.ToString();
374 succeeded = UInt32.TryParse(current.
ToString(), out value);
380 longParent.Append(
".").Append(value);
381 succeeded = UInt32.TryParse(current.
ToString(), out value);
382 current.Assert(succeeded,
"not a decimal");
386 parent = longParent.ToString();
390 longParent.Append(
".");
391 longParent.Append(current);
392 current = symbols.NextNonEOLSymbol();
394 longParent.Append(current);
395 current = symbols.NextNonEOLSymbol();
396 succeeded = UInt32.TryParse(current.
ToString(), out value);
397 current.Assert(succeeded,
"not a decimal");
398 longParent.Append(current);
399 current = symbols.NextNonEOLSymbol();
401 longParent.Append(current);
413 Symbol startSymbol = symbols.NextNonEOLSymbol();
414 Symbol current = startSymbol;
419 Symbol value1Symbol = symbols.NextNonEOLSymbol();
429 Int64? value1 = DecodeNumber(value1Symbol);
430 if (!value1.HasValue)
432 value1Symbol.Assert(
false,
"Invalid range declaration!");
437 current = symbols.NextNonEOLSymbol();
442 Symbol value2Symbol = symbols.NextNonEOLSymbol();
443 Int64? value2 = DecodeNumber(value2Symbol);
444 value2Symbol.Assert(value2.HasValue && (value2.Value >= value1.Value),
"Invalid range declaration!");
446 if (value2.Value == value1.Value)
452 range =
new ValueRange(value1.Value, value2.Value);
455 current = symbols.NextNonEOLSymbol();
466 value1Symbol.Assert(range.
Start >= 0,
"Invalid range declaration! Size must be greater than 0");
477 current = symbols.NextNonEOLSymbol();
482 for (
int i=0; i<result.Count; i++)
484 for (
int k=i+1; k<result.Count; k++)
486 startSymbol.Assert(!result[i].IntersectsWith(result[k]),
"Invalid range declaration! Overlapping of ranges!");
496 string numString = (number != null) ? number.
ToString() : null;
498 if (!String.IsNullOrEmpty(numString))
500 if (numString.StartsWith(
"'") && (numString.Length > 3))
503 int end = numString.IndexOf(
'\'', 1);
504 if (end == (numString.Length - 2))
508 switch (numString[numString.Length - 1])
512 result = Convert.ToInt64(numString.Substring(1, numString.Length - 3), 2);
516 result = Convert.ToInt64(numString.Substring(1, numString.Length - 3), 16);
525 else if (Int64.TryParse(numString, out result))
536 Symbol current = symbols.NextNonEOLSymbol();
542 current = symbols.NextNonEOLSymbol();
543 string identifier = current.
ToString();
545 current = symbols.NextNonEOLSymbol();
548 current = symbols.NextNonEOLSymbol();
550 if (Int64.TryParse(current.
ToString(), out enumValue))
555 map.Add(enumValue, String.Format(
"{0}({1})", identifier, enumValue));
557 catch (ArgumentException ex)
559 current.Assert(
false, ex.Message);
567 current = symbols.NextNonEOLSymbol();
570 current = symbols.NextNonEOLSymbol();
static readonly Symbol Pipe
static readonly Symbol IpAddress
The CHOICE type represents a list of alternatives..
static readonly Symbol TextualConvention
The SEQUENCE type represents a set of specified types. This is roughtly analogous to a ...
static void ParseOidValue(ISymbolEnumerator symbols, out string parent, out uint value)
static readonly Symbol Object
static ValueRanges DecodeRanges(ISymbolEnumerator symbols)
static readonly Symbol Octet
static readonly Symbol Comma
static readonly Symbol DoubleDot
bool PutBack(Symbol item)
Description of MibException.
static readonly Symbol Bits
ISymbolEnumerator GetEnumerator()
static readonly Symbol Opaque
static Int64 DecodeNumber(Symbol number)
static ValueMap DecodeEnumerations(ISymbolEnumerator symbols)
The INTEGER type represents a list of alternatives, or a range of numbers.. Includes Integer32 as it'...
static readonly Symbol Identifier
Lexer(string file, TextReader stream)
static readonly Symbol OpenParentheses
static readonly Symbol OpenBracket
Lexer class that parses MIB files into symbol list.
static readonly Symbol Comment
static MibException Create(string message, Symbol symbol)
Creates a MibException with a specific Symbol.
static readonly Symbol Sequence
static readonly Symbol Of
static readonly Symbol Size
static readonly Symbol CloseParentheses
static ITypeAssignment ParseBasicTypeDef(IModule module, string name, ISymbolEnumerator symbols, bool isMacroSyntax=false)
static readonly Symbol CloseBracket
override string ToString()
Returns a String that represents this Symbol.
The SEQUENCE OF type represents a list of data sets..
static readonly Symbol Choice
static readonly Symbol String