public UtilsInputFiles (String inputString) {
// nothing to parse?
if (String.IsNullOrWhiteSpace (inputString))
return;
// tokenize input strings which are easier to parse (see documentation of function)
String[] tokens = TokenizeInputString (inputString);
// -----------------------------------------------------------------
// parse tokens
PS parserState;
String lastKey = "";
Dictionary<String, String> curDict = null;
// parse tokens with "Finite-State Machine"
Action<String>[,] stateMachineMapping = new Action<String>[(int)PS.NUM_PARSER_STATES, (int)TT.NUM_TOKEN_TYPES];
for (int parserStateIndex = 0; parserStateIndex < (int)PS.NUM_PARSER_STATES; parserStateIndex++) {
stateMachineMapping [parserStateIndex, (int)TT.OPEN] = delegate { throw new Exception("Unexpected '<'"); };
stateMachineMapping [parserStateIndex, (int)TT.CLOSE] = delegate { throw new Exception("Unexpected '>'"); };
stateMachineMapping [parserStateIndex, (int)TT.COMMA] = delegate { throw new Exception("Unexpected ','"); };
stateMachineMapping [parserStateIndex, (int)TT.ASSIGN] = delegate { throw new Exception("Unexpected '='"); };
stateMachineMapping [parserStateIndex, (int)TT.STRING] = delegate(String str) { throw new Exception("Unexpected string \"" + str + "\""); };
}
// some more functional goodness
Action<PS, TT, PS, Action<String>> map = delegate(PS _parserState, TT _tokenType, PS _nextParserState, Action<string> _action) {
stateMachineMapping[(int)_parserState, (int)_tokenType] = delegate(String str) {
if(_action != null) _action(str);
parserState = _nextParserState;
};
};
// create connections/mappings for state machine
map (PS.PLIST_OPEN, TT.CLOSE, PS.PLIST_CLOSE, null );
map (PS.PLIST_OPEN, TT.STRING, PS.PLIST_KEY, (String str) => { lastKey = str; } );
map (PS.PLIST_KEY, TT.ASSIGN, PS.PLIST_ASSIGN, null );
map (PS.PLIST_ASSIGN, TT.STRING, PS.PLIST_VALUE, (String str) => { curDict.Add(lastKey, str); } );
map (PS.PLIST_VALUE, TT.COMMA, PS.PLIST_COMMA, null );
map (PS.PLIST_VALUE, TT.CLOSE, PS.PLIST_CLOSE, null );
map (PS.PLIST_COMMA, TT.STRING, PS.PLIST_KEY, (String str) => { lastKey = str; } );
map (PS.PLIST_CLOSE, TT.STRING, PS.FLIST_FILENAME, (String str) => { m_dataEntries.Add (new DataEntry (str, curDict)); curDict = null; } );
map (PS.FLIST_COMMA, TT.OPEN, PS.PLIST_OPEN, (String str) => { curDict = new Dictionary<String, String>(); } );
map (PS.FLIST_COMMA, TT.STRING, PS.FLIST_FILENAME, (String str) => { m_dataEntries.Add (new DataEntry (str, curDict)); curDict = null; } );
map (PS.FLIST_COMMA, TT.COMMA, PS.FLIST_COMMA, (String str) => { m_dataEntries.Add (new DataEntry (null, curDict)); curDict = null; } );
map (PS.FLIST_FILENAME, TT.COMMA, PS.FLIST_COMMA, null );
// follow state machine to end
parserState = PS.FLIST_COMMA;
foreach (String token in tokens)
stateMachineMapping [(int)parserState, (int)StringToTokenType (token)] (EscapeSequencesToNormalChar (token));
// depending on last state there could be errors
switch (parserState) {
case PS.PLIST_CLOSE:
case PS.FLIST_COMMA:
// insert missing file
m_dataEntries.Add (new DataEntry (null, curDict));
break;
case PS.PLIST_OPEN:
case PS.PLIST_COMMA:
case PS.PLIST_KEY:
case PS.PLIST_ASSIGN:
case PS.PLIST_VALUE:
throw new Exception ("Property list didn't get finished! Missing '>'!");
case PS.FLIST_FILENAME:
// add null-file
break;
}
}