16 #region Using directives
21 using System.Collections;
30 internal class Grammar
32 #region Fields and constants
37 public const string FileHeader =
"GOLD Parser Tables/v1.0";
40 private string m_name;
41 private string m_version;
42 private string m_author;
43 private string m_about;
44 private int m_startSymbolIndex;
45 private bool m_caseSensitive;
48 private Symbol[] m_symbolTable;
49 private String[] m_charSetTable;
50 internal Rule[] m_ruleTable;
51 internal DfaState[] m_dfaStateTable;
52 internal LRState[] m_lrStateTable;
55 internal int m_dfaInitialStateIndex;
56 internal DfaState m_dfaInitialState;
57 internal int m_lrInitialState;
60 private BinaryReader m_reader;
61 private int m_entryCount;
63 internal Symbol m_errorSymbol;
64 internal Symbol m_endSymbol;
74 public Grammar(BinaryReader reader)
78 throw new ArgumentNullException(
"reader");
87 #region Public members
92 public Symbol[] SymbolTable
105 get {
return m_name; }
111 public string Version
113 get {
return m_version; }
121 get {
return m_author; }
129 get {
return m_about; }
135 public Symbol StartSymbol
137 get {
return m_symbolTable[m_startSymbolIndex]; }
143 public bool CaseSensitive
145 get {
return m_caseSensitive; }
151 public DfaState DfaInitialState
153 get {
return m_dfaInitialState; }
159 public LRState InitialLRState
161 get {
return m_lrStateTable[m_lrInitialState]; }
167 public Symbol EndSymbol
169 get {
return m_endSymbol; }
174 #region Private members
181 if (FileHeader != ReadString())
183 throw new FileLoadException(SR.GetString(SR.Grammar_WrongFileHeader));
185 while (m_reader.PeekChar() != -1)
187 RecordType recordType = ReadNextRecord();
190 case RecordType.Parameters:
194 case RecordType.TableCounts:
198 case RecordType.Initial:
202 case RecordType.Symbols:
206 case RecordType.CharSets:
210 case RecordType.Rules:
214 case RecordType.DfaStates:
218 case RecordType.LRStates:
223 throw new FileLoadException(SR.GetString(SR.Grammar_InvalidRecordType));
226 m_dfaInitialState = m_dfaStateTable[m_dfaInitialStateIndex];
227 OptimizeDfaTransitionVectors();
234 private RecordType ReadNextRecord()
236 char recordType = (char) ReadByte();
242 m_entryCount = ReadInt16();
243 return (RecordType) ReadByteEntry();
246 throw new FileLoadException(SR.GetString(SR.Grammar_InvalidRecordHeader));
253 private void ReadHeader()
255 m_name = ReadStringEntry();
256 m_version = ReadStringEntry();
257 m_author = ReadStringEntry();
258 m_about = ReadStringEntry();
259 m_caseSensitive = ReadBoolEntry();
260 m_startSymbolIndex = ReadInt16Entry();
266 private void ReadTableCounts()
269 m_symbolTable =
new Symbol [ReadInt16Entry()];
270 m_charSetTable =
new String [ReadInt16Entry()];
271 m_ruleTable =
new Rule [ReadInt16Entry()];
272 m_dfaStateTable =
new DfaState [ReadInt16Entry()];
273 m_lrStateTable =
new LRState [ReadInt16Entry()];
279 private void ReadInitialStates()
281 m_dfaInitialStateIndex = ReadInt16Entry();
282 m_lrInitialState = ReadInt16Entry();
288 private void ReadSymbols()
290 int index = ReadInt16Entry();
291 string name = ReadStringEntry();
292 SymbolType symbolType = (SymbolType) ReadInt16Entry();
294 Symbol symbol =
new Symbol(index, name, symbolType);
297 case SymbolType.Error:
298 m_errorSymbol = symbol;
302 m_endSymbol = symbol;
305 m_symbolTable[index] = symbol;
311 private void ReadCharSets()
313 m_charSetTable[ReadInt16Entry()] = ReadStringEntry();
319 private void ReadRules()
321 int index = ReadInt16Entry();
322 Symbol nonTerminal = m_symbolTable[ReadInt16Entry()];
324 Symbol[] symbols =
new Symbol[m_entryCount];
325 for (
int i = 0 ; i < symbols.Length; i++)
327 symbols[i] = m_symbolTable[ReadInt16Entry()];
329 Rule rule =
new Rule(index, nonTerminal, symbols);
330 m_ruleTable[index] = rule;
336 private void ReadDfaStates()
338 int index = ReadInt16Entry();
339 Symbol acceptSymbol = null;
340 bool acceptState = ReadBoolEntry();
343 acceptSymbol = m_symbolTable[ReadInt16Entry()];
352 DfaEdge[] edges =
new DfaEdge[m_entryCount / 3];
353 for (
int i = 0; i < edges.Length; i++)
355 edges[i].CharSetIndex = ReadInt16Entry();
356 edges[i].TargetIndex = ReadInt16Entry();
361 ObjectMap transitionVector = CreateDfaTransitionVector(edges);
362 DfaState dfaState =
new DfaState(index, acceptSymbol, transitionVector);
363 m_dfaStateTable[index] = dfaState;
369 private void ReadLRStates()
371 int index = ReadInt16Entry();
373 LRStateAction[] stateTable =
new LRStateAction[m_entryCount / 4];
374 for (
int i = 0; i < stateTable.Length; i++)
376 Symbol symbol = m_symbolTable[ReadInt16Entry()];
377 LRAction action = (LRAction) ReadInt16Entry();
378 int targetIndex = ReadInt16Entry();
380 stateTable[i] =
new LRStateAction(i, symbol, action, targetIndex);
384 LRStateAction[] transitionVector =
new LRStateAction[m_symbolTable.Length];
385 for (
int i = 0; i < transitionVector.Length; i++)
387 transitionVector[i] = null;
389 for (
int i = 0; i < stateTable.Length; i++)
391 transitionVector[stateTable[i].Symbol.Index] = stateTable[i];
394 LRState lrState =
new LRState(index, stateTable, transitionVector);
395 m_lrStateTable[index] = lrState;
403 private ObjectMap CreateDfaTransitionVector(DfaEdge[] edges)
405 ObjectMap transitionVector =
new ObjectMap();
406 for (
int i = edges.Length; --i >= 0;)
408 string charSet = m_charSetTable[edges[i].CharSetIndex];
409 for (
int j = 0; j < charSet.Length; j++)
411 transitionVector[charSet[j]] = edges[i].TargetIndex;
414 return transitionVector;
420 private void ReadEmptyEntry()
422 if (ReadEntryType() != EntryType.Empty)
424 throw new FileLoadException(SR.GetString(SR.Grammar_EmptyEntryExpected));
433 private string ReadStringEntry()
435 if (ReadEntryType() != EntryType.String)
437 throw new FileLoadException(SR.GetString(SR.Grammar_StringEntryExpected));
447 private int ReadInt16Entry()
449 if (ReadEntryType() != EntryType.Integer)
451 throw new FileLoadException(SR.GetString(SR.Grammar_IntegerEntryExpected));
461 private byte ReadByteEntry()
463 if (ReadEntryType() != EntryType.Byte)
465 throw new FileLoadException(SR.GetString(SR.Grammar_ByteEntryExpected));
475 private bool ReadBoolEntry()
477 if (ReadEntryType() != EntryType.Boolean)
479 throw new FileLoadException(SR.GetString(SR.Grammar_BooleanEntryExpected));
489 private EntryType ReadEntryType()
491 if (m_entryCount == 0)
493 throw new FileLoadException(SR.GetString(SR.Grammar_NoEntry));
495 return (EntryType) ReadByte();
502 private string ReadString()
504 StringBuilder result =
new StringBuilder();
505 char unicodeChar = (char) ReadInt16();
506 while (unicodeChar != (
char) 0)
508 result.Append(unicodeChar);
509 unicodeChar = (char) ReadInt16();
511 return result.ToString();
518 private int ReadInt16()
520 return m_reader.ReadUInt16();
527 private byte ReadByte()
529 return m_reader.ReadByte();
536 private bool ReadBool()
538 return (ReadByte() == 1);
541 private void OptimizeDfaTransitionVectors()
543 DfaState[] dfaStates = m_dfaStateTable;
544 foreach (DfaState state
in dfaStates)
546 ObjectMap transitions = state.m_transitionVector;
547 for (
int i = transitions.Count; --i >= 0;)
549 int key = transitions.GetKey(i);
550 object transition = transitions[key];
551 if (transition != null)
553 int transitionIndex = (int) transition;
554 if (transitionIndex >= 0)
556 transitions[key] = dfaStates[transitionIndex];
560 transitions[key] = null;
564 transitions.ReadOnly =
true;
570 #region Private type definitions
575 private enum RecordType
577 Parameters = (int)
'P',
578 TableCounts = (
int)
'T',
581 CharSets = (int)
'C',
583 DfaStates = (int)
'D',
584 LRStates = (
int)
'L',
591 private enum EntryType
603 private struct DfaEdge
605 public int CharSetIndex;
606 public int TargetIndex;