Пример #1
0
 public static void VerifyIsIdentifier(this INextAwareEnumerator <Token> enumerator)
 {
     if (!LuaToken.IsIdentifier(enumerator.Current.Value))
     {
         throw new UnexpectedTokenException(enumerator.Current);
     }
 }
Пример #2
0
        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());
        }
Пример #3
0
        internal bool match(LuaToken expected)
        {
            Token token = lookAhead(0);

            if (token.getType() != expected)
            {
                return(false);
            }

            consume();
            return(true);
        }
Пример #4
0
        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);
        }
Пример #5
0
        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);
        }
Пример #6
0
            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.");
                }
            }
Пример #7
0
        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);
        }
Пример #9
0
        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;
            }
            ;
        }
Пример #10
0
        }         // 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
Пример #11
0
        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());
        }
Пример #12
0
		/// <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
Пример #13
0
		} // 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
Пример #14
0
        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
Пример #15
0
        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;
        }
Пример #16
0
		} // 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
Пример #17
0
		} // 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
Пример #18
0
 private KeyValuePair <LuaToken, string> T(LuaToken t, string v)
 {
     return(new KeyValuePair <LuaToken, string>(t, v));
 } // func T
Пример #19
0
 internal LuaTokenData(LuaToken token, int id, string symbol)
 {
     this.token  = token;
     this.id     = id;
     this.symbol = symbol;
 }
Пример #20
0
 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)));
 }
Пример #21
0
 private KeyValuePair<LuaToken, string> T(LuaToken t, string v)
 {
   return new KeyValuePair<LuaToken, string>(t, v);
 } // func T