public static void VerifyIsIdentifier(this INextAwareEnumerator <Token> enumerator) { if (!LuaToken.IsIdentifier(enumerator.Current.Value)) { throw new UnexpectedTokenException(enumerator.Current); } }
internal Token consume(LuaToken expected) { Token token = lookAhead(0); if (token.getType() != expected) { throw new Exception("Expected token " + expected + " and found " + token.getType() + " " + token.Text); } return(consume()); }
internal bool match(LuaToken expected) { Token token = lookAhead(0); if (token.getType() != expected) { return(false); } consume(); return(true); }
public void EditFile <T>(string property, Action <T> modify) where T : LuaToken { var keys = property.Split('.'); //always one element least in the current version (long winter update) LuaToken val = _saveFile.LuaState[0]; for (int i = 0; i < keys.Length; i++) { val = val[keys[i]]; } modify(val as T); }
public static LuaExpression ReadExpression(INextAwareEnumerator <Token> reader, IParserContext context) { var expressionParser = ExpressionParserDiscriminator.Identify(reader, context); var expression = expressionParser.Parse(reader, context); if (LuaToken.IsBinaryOperation(reader.Current.Value)) { var operation = reader.GetAndMoveNext(); var rightSideExpression = ReadExpression(reader, context); expression = new BinaryExpression(expression, rightSideExpression, operation.Value); } return(expression); }
public LuaFieldToken(LuaToken key, object value) : base(LuaTokenTypes.LUA_FIELD) { switch (key.getTokenType()) { case LuaTokenTypes.LUA_INTEGER: case LuaTokenTypes.LUA_KEYWORD: case LuaTokenTypes.LUA_STRING: m_keyValue = new KeyValuePair <IComparable, object>((IComparable)key.getValue(), value); break; default: throw new InvalidDataException("Don't know how to hash by " + key.getTokenType() + " token type."); } }
public static SavedVariablesDictionary parse(string sFileName) { SavedVariablesDictionary savedVariables = new SavedVariablesDictionary(); // Note -- file errors are deliberately allowed to bubble to the caller. // Note 2: This function reads in the entire file. There are undoubtedly better ways to do this. SavedVariablesFileStream stream = new SavedVariablesFileStream(sFileName); for (LuaToken variable = getNextToken(stream); variable != null; variable = getNextToken(stream)) { if (stream.getNextCharacter(false) != '=') { throw new InvalidDataException("Expected 'variable_name = value' pairs in saved variables file."); } savedVariables.Add(((LuaKeywordToken)variable).getKeyword(), getNextToken(stream).getInterpretedValue()); } /* * // Sanity check tests * // First, Save -> Reload should yield equivalent databases * // Second, Save File 1 -> Load File 1 -> Save File 2 should yield identical files * * string sExportTest = "c:\\sv\\original\\" + sFileName.Substring(sFileName.LastIndexOf('\\')); * string sReexportTest = "c:\\sv\\reexport\\" + sFileName.Substring(sFileName.LastIndexOf('\\')); * * if (sFileName != sExportTest) * { * // Test export functionality * export(sExportTest, savedVariables); * // And reimport test file * SavedVariablesDictionary reimport = parse(sExportTest); * * if (!savedVariables.Equivalent(reimport)) * { * throw new InvalidDataException("Export file does not match import file."); * } * * // And test export the reimport * export(sReexportTest, reimport); * } */ stream = null; return(savedVariables); }
public static IExpressionParser Identify(INextAwareEnumerator <Token> reader, IParserContext context) { if (reader.Current.Type == TokenType.StringConstant) { return(new StringConstantExpressionParser()); } if (LuaToken.IsIdentifier(reader.Current.Value) && reader.HasNext && (reader.Next.Value == LuaToken.Dot || reader.Next.Value == LuaToken.LeftSquareBracket)) { TableExpressionParserDiscriminator.Identify(reader, context); } if (reader.Current.Value == LuaToken.LeftBracket) { return(new BracketedExpressionParser()); } if (LuaToken.IsIdentifier(reader.Current.Value) && reader.HasNext && reader.Next.Value == LuaToken.LeftBracket) { return(new FunctionCallExpressionParser()); } if (reader.Current.Type == TokenType.BooleanConstant) { return(new BooleanConstantExpressionParser()); } if (LuaToken.IsIdentifier(reader.Current.Value)) { return(new SingleVariableExpressionParser()); } if (LuaToken.IsNumericConstant(reader.Current.Value)) { return(new NumericConstantExpressionParser()); } if (reader.Current.Value == LuaToken.LeftCurlyBrace) { return(new TableInitializerExpressionParser()); } throw new UnexpectedTokenException(reader.Current); }
public void SaveValue(LuaToken value) { if (value == null) { _luaBinWriter.Write(LUABINS_NIL); return; } switch (value.TokenType) { case LuaTokenType.Table: _luaBinWriter.Write(LUABINS_TABLE); WriteTable(value as LuaTable); return; case LuaTokenType.Double: _luaBinWriter.Write(LUABINS_NUMBER); _luaBinWriter.Write((double)value); return; case LuaTokenType.String: _luaBinWriter.Write(LUABINS_STRING); var s = (string)value; _luaBinWriter.Write(s.Length); _luaBinWriter.Write(Encoding.ASCII.GetBytes(s)); return; case LuaTokenType.Boolean: if ((bool)value) { _luaBinWriter.Write(LUABINS_TRUE); } else { _luaBinWriter.Write(LUABINS_FALSE); } return; } ; }
} // func ParseSource #region -- FindMatchToken --------------------------------------------------------- private NeoLuaToken FindMatchToken(NeoLuaToken current, LuaToken incToken, LuaToken decToken, bool lNext) { int iNested = 0; while (current != null) { if (current.Token == incToken) { iNested++; } else if (current.Token == decToken) { iNested--; if (iNested == 0) { return(current); } } current = lNext ? current.Next : current.Prev; } return(null); } // func FindMatchToken
private static LuaToken getNextToken(SavedVariablesFileStream stream) { // Note: // The general rule on the true/false parameter of getNextCharacter/peekNextCharacter. // That boolean indicates whether the function should parse out comments & white-spaces // from the next possible character. While it's useful to ignore those characters // when talking about separators between keywords, those characters should not // be ignored when the next keyword is being processed. Imagine the following // example: // var1 = 0xc0 // ffee = 72 // In this case, if we were processing the numer '0xc0' and asked for the next // character ignoring white spaces, 'ffee' would be appended letting var1 = 0xc0ffee // when in actuality ffee is the name of the next keyword / variable. char?cCharacter = stream.getNextCharacter(false); if (cCharacter == null) { return(null); } if ((cCharacter >= '0' && cCharacter <= '9') || (cCharacter == '-' || cCharacter == '+')) { char?cNextCharacter = stream.peekNextCharacter(true); // Numeric token if (cCharacter == '0' && cNextCharacter != null && Char.ToUpper((char)cNextCharacter) == 'X') { // Hexadecimal character long lValue = 0; // Consume 'X' stream.getNextCharacter(true); while (true) { cNextCharacter = stream.peekNextCharacter(true); if (cNextCharacter != null && Char.ToUpper((char)cNextCharacter) >= 'A' && Char.ToUpper((char)cNextCharacter) <= 'F') { lValue = lValue * 16 + (10 + (char)cNextCharacter - 'A'); } else if (cNextCharacter >= '0' && (char)cNextCharacter <= '9') { lValue = lValue * 16 + (char)cNextCharacter - '0'; } else { break; } // Consume the character we just read in stream.getNextCharacter(true); } return(new LuaIntegerToken(lValue)); } else { // Numeric token -- scan for the whole string then choose the number format String sValue = null; bool bIsInteger = true; sValue += cCharacter; while (true) { cNextCharacter = stream.peekNextCharacter(true); if (cNextCharacter == 'e' || cNextCharacter == 'E' || cNextCharacter == '.' || cNextCharacter == '-') { bIsInteger = false; } else if (!(cNextCharacter >= '0' && cNextCharacter <= '9')) { break; } sValue += cNextCharacter; // Consume the character we just read in stream.getNextCharacter(true); } if (bIsInteger) { return(new LuaIntegerToken(Int64.Parse(sValue))); } else { return(new LuaDoubleToken(Double.Parse(sValue, System.Globalization.CultureInfo.InvariantCulture))); } } } else if (cCharacter == '"' || cCharacter == '\'') { string sValue = ""; while (true) { char?cNextCharacter = stream.getNextCharacter(true); // String terminates when it ends with the same character // it began with (i.e. ' is needed to close ', and " for ") if (cNextCharacter == cCharacter) { break; } else if (cNextCharacter == null) { throw new InvalidDataException("Unterminated lua string."); } else if (cNextCharacter == '\\') { // Escape the next character... Read it in whatever it is. cNextCharacter = stream.getNextCharacter(true); switch (cNextCharacter) { case '0': cNextCharacter = '\0'; break; case 'a': cNextCharacter = '\a'; break; case 'b': cNextCharacter = '\b'; break; case 'f': cNextCharacter = '\f'; break; case 'n': cNextCharacter = '\n'; break; case 'r': cNextCharacter = '\r'; break; case 't': cNextCharacter = '\t'; break; case 'v': cNextCharacter = '\v'; break; case '\'': case '\"': // These types pass through break; default: // If it's an escape sequence we don't understand // just reproduce it. Sometimes it's not properly formatted // strings (e.g. !Swatter had some paths that used the '\' from // the path separator without escape codes) sValue += '\\'; break; } } sValue += cNextCharacter; } return(new LuaStringToken(sValue)); } else if (cCharacter == '[') { LuaToken key = getNextToken(stream); if (key == null) { throw new InvalidDataException("Expected a field identifier after ["); } else if (stream.getNextCharacter(false) != ']') { throw new InvalidDataException("Expected a ] after field key"); } else if (stream.getNextCharacter(false) != '=') { throw new InvalidDataException("Expected a value after field key"); } else { LuaToken value = getNextToken(stream); if (value == null) { throw new InvalidDataException("Expected value after [" + key + "] = "); } return(new LuaFieldToken(key, value.getInterpretedValue())); } } else if (cCharacter == '{') { SavedVariablesDictionary items = new SavedVariablesDictionary(); long lAnonymousKey = 1; while (true) { char?cNextCharacter = stream.peekNextCharacter(false); if (cNextCharacter == null) { throw new InvalidDataException("Unterminated lua table (no '}' after '{' in file)."); } else if (cNextCharacter == '}') { // Consume the close brackets stream.getNextCharacter(false); break; } else if (cNextCharacter == ',' || cNextCharacter == ';') { stream.getNextCharacter(false); } else { LuaToken nextToken = getNextToken(stream); if (nextToken == null) { throw new InvalidDataException("Unterminated lua table (no '}' after '{' in file)."); } // Case 1: [key] = value pair if (nextToken.getTokenType() == LuaTokenTypes.LUA_FIELD) { items.Add(((LuaFieldToken)nextToken).getKeyValueKey(), ((LuaFieldToken)nextToken).getKeyValueValue()); } else if (stream.peekNextCharacter(false) == '=') // Case 2: key = value pair { // Consume the '=' stream.getNextCharacter(false); switch (nextToken.getTokenType()) { case LuaTokenTypes.LUA_INTEGER: case LuaTokenTypes.LUA_KEYWORD: case LuaTokenTypes.LUA_STRING: items.Add((IComparable)nextToken.getValue(), getNextToken(stream).getInterpretedValue()); break; default: throw new InvalidDataException("Don't know how to hash by " + nextToken.getTokenType() + " token type."); } } else // Case 3: value { items.Add(lAnonymousKey++, nextToken.getInterpretedValue()); } } } return(new LuaTableToken(items)); } else if ((cCharacter >= 'a' && cCharacter <= 'z') || (cCharacter >= 'A' && cCharacter <= 'Z') || cCharacter == '_') { string sKeyword = null; sKeyword += cCharacter; while (true) { char?cNextCharacter = stream.peekNextCharacter(true); if ((cNextCharacter >= 'a' && cNextCharacter <= 'z') || (cNextCharacter >= 'A' && cNextCharacter <= 'Z') || (cNextCharacter >= '0' && cNextCharacter <= '9') || cNextCharacter == '_') { sKeyword += stream.getNextCharacter(true); } else { return(new LuaKeywordToken(sKeyword)); } } } throw new InvalidDataException("Can't parse string " + stream.getErrorContext()); }
/// <summary>Erzeugt einen Token.</summary> /// <param name="iKind">Type des Wertes.</param> /// <param name="sValue">Der Wert.</param> /// <param name="fStart">Beginn des Tokens</param> /// <param name="fEnd">Ende des Tokens</param> internal Token(LuaToken iKind, string sValue, Position fStart, Position fEnd) { this.iKind = iKind; this.fStart = fStart; this.fEnd = fEnd; this.sValue = sValue; } // ctor
} // proc ReadTextBlock #endregion /// <summary>Resolves the name of the token.</summary> /// <param name="type"></param> /// <returns></returns> public static string GetTokenName(LuaToken type) { Type tokenType = typeof(LuaToken); TypeInfo ti = tokenType.GetTypeInfo(); string sName = Enum.GetName(tokenType, type); FieldInfo fi = ti.GetDeclaredField(sName); if (fi != null) { var tokenName = fi.GetCustomAttribute<TokenNameAttribute>(); if (tokenName != null) sName = tokenName.Name; } return sName; } // func GetTokenName
private static ConsoleColor GetTokenColor(LuaToken typ) { switch (typ) { case LuaToken.KwAnd: case LuaToken.KwBreak: case LuaToken.KwCast: case LuaToken.KwConst: case LuaToken.KwDo: case LuaToken.KwElse: case LuaToken.KwElseif: case LuaToken.KwEnd: case LuaToken.KwFalse: case LuaToken.KwFor: case LuaToken.KwForEach: case LuaToken.KwFunction: case LuaToken.KwGoto: case LuaToken.KwIf: case LuaToken.KwIn: case LuaToken.KwLocal: case LuaToken.KwNil: case LuaToken.KwNot: case LuaToken.KwOr: case LuaToken.KwRepeat: case LuaToken.KwReturn: case LuaToken.KwThen: case LuaToken.KwTrue: case LuaToken.KwUntil: case LuaToken.KwWhile: case LuaToken.DotDotDot: return(ConsoleColor.White); case LuaToken.Comment: case LuaToken.InvalidComment: return(ConsoleColor.Green); case LuaToken.String: case LuaToken.InvalidString: return(ConsoleColor.DarkYellow); case LuaToken.Assign: case LuaToken.BitAnd: case LuaToken.BitOr: case LuaToken.BracketClose: case LuaToken.BracketCurlyClose: case LuaToken.BracketCurlyOpen: case LuaToken.BracketOpen: case LuaToken.BracketSquareClose: case LuaToken.BracketSquareOpen: case LuaToken.Colon: case LuaToken.Comma: case LuaToken.Dot: case LuaToken.DotDot: case LuaToken.Equal: case LuaToken.Greater: case LuaToken.GreaterEqual: case LuaToken.Lower: case LuaToken.LowerEqual: case LuaToken.Minus: case LuaToken.NotEqual: case LuaToken.Percent: case LuaToken.Semicolon: case LuaToken.ShiftLeft: case LuaToken.ShiftRight: case LuaToken.Slash: case LuaToken.SlashShlash: case LuaToken.Star: return(ConsoleColor.DarkGray); case LuaToken.Number: return(ConsoleColor.DarkCyan); case LuaToken.InvalidChar: return(ConsoleColor.Red); default: return(ConsoleColor.Gray); } } // func GetTokenColor
private NeoLuaToken FindMatchToken(NeoLuaToken current, LuaToken incToken, LuaToken decToken, bool lNext) { int iNested = 0; while (current != null) { if (current.Token == incToken) iNested++; else if (current.Token == decToken) { iNested--; if (iNested == 0) return current; } current = lNext ? current.Next : current.Prev; } return null; }
} // func CreateToken /// <summary>Erzeugt einen Token</summary> /// <param name="iKind">Art des Tokens</param> /// <param name="iNewState"></param> /// <returns>Token</returns> private Token EatCharAndCreateToken(int iNewState, LuaToken iKind) { EatChar(iNewState); return CreateToken(iNewState, iKind); } // func CreateToken
} // proc NextChar /// <summary>Erzeugt einen Token</summary> /// <param name="iKind">Art des Tokens</param> /// <param name="iNewState"></param> /// <returns>Token</returns> private Token CreateToken(int iNewState, LuaToken iKind) { iState = iNewState; Token tok = new Token(iKind, CurValue, fStart, fEnd); fStart = fEnd; sbCur = null; return tok; } // func CreateToken
private KeyValuePair <LuaToken, string> T(LuaToken t, string v) { return(new KeyValuePair <LuaToken, string>(t, v)); } // func T
internal LuaTokenData(LuaToken token, int id, string symbol) { this.token = token; this.id = id; this.symbol = symbol; }
private static Token FetchToken(LuaToken typ, LuaLexer code, bool lOptional = false) { if (code.Current.Typ == typ) { var t = code.Current; code.Next(); return t; } else if (lOptional) return null; else throw ParseError(code.Current, String.Format(Properties.Resources.rsParseUnexpectedToken, LuaLexer.GetTokenName(code.Current.Typ), LuaLexer.GetTokenName(typ))); }
private KeyValuePair<LuaToken, string> T(LuaToken t, string v) { return new KeyValuePair<LuaToken, string>(t, v); } // func T