Exemplo n.º 1
0
 private string getValueString(string str)
 {
     if ((emuera == null) || (GlobalStatic.EMediator == null))
     {
         return("");
     }
     if (string.IsNullOrEmpty(str))
     {
         return("");
     }
     mainConsole.RunERBFromMemory = true;
     try
     {
         StringStream   st    = new StringStream(str);
         WordCollection wc    = LexicalAnalyzer.Analyse(st, LexEndWith.EoL, LexAnalyzeFlag.None);
         IOperandTerm   term  = ExpressionParser.ReduceExpressionTerm(wc, TermEndWith.EoL);
         SingleTerm     value = term.GetValue(GlobalStatic.EMediator);
         return(value.ToString());
     }
     catch (CodeEE e)
     {
         return(e.Message);
     }
     catch (Exception e)
     {
         return(e.GetType().ToString() + ":" + e.Message);
     }
     finally
     {
         mainConsole.RunERBFromMemory = false;
     }
 }
Exemplo n.º 2
0
 internal double Calculate()
 {
     LexicalAnalyzer = new LexicalAnalyzer(Input);
     RPNConverter    = new RPNConverter(LexicalAnalyzer.Analyse());
     RPNComputer     = new RPNComputer(RPNConverter.Convert());
     return(RPNComputer.Compute());
 }
Exemplo n.º 3
0
        private void analyzeSharpDim(StringStream st, ScriptPosition position, bool dims)
        {
            var wc   = LexicalAnalyzer.Analyse(st, LexEndWith.EoL, LexAnalyzeFlag.AllowAssignment);
            var data = UserDefinedVariableData.Create(wc, dims, false, position);

            if (data.Reference)
            {
                throw new NotImplCodeEE();
            }
            VariableToken var = null;

            if (data.CharaData)
            {
                var = parentProcess.VEvaluator.VariableData.CreateUserDefCharaVariable(data);
            }
            else
            {
                var = parentProcess.VEvaluator.VariableData.CreateUserDefVariable(data);
            }
            idDic.AddUseDefinedVariable(var);
        }
Exemplo n.º 4
0
        public static LogicalLine ParseLine(StringStream stream, ScriptPosition position, EmueraConsole console)
        {
            var lineNo = position.LineNo;
            var errMes = "";

            LexicalAnalyzer.SkipWhiteSpace(stream); //先頭のホワイトスペースを読み飛ばす
            if (stream.EOS)
            {
                return(null);
            }
            //コメント行かどうかはここに来る前に判定しておく
            try
            {
                #region 前置インクリメント、デクリメント行

                if (stream.Current == '+' || stream.Current == '-')
                {
                    var op   = stream.Current;
                    var wc   = LexicalAnalyzer.Analyse(stream, LexEndWith.EoL, LexAnalyzeFlag.None);
                    var opWT = wc.Current as OperatorWord;
                    if (opWT == null || opWT.Code != OperatorCode.Increment && opWT.Code != OperatorCode.Decrement)
                    {
                        if (op == '+')
                        {
                            errMes = "行が\'+\'から始まっていますが、インクリメントではありません";
                        }
                        else
                        {
                            errMes = "行が\'-\'から始まっていますが、デクリメントではありません";
                        }
                        goto err;
                    }
                    wc.ShiftNext();
                    //token = EpressionParser.単語一個分取得(wc)
                    //token非変数
                    //token文字列形
                    //token変更不可能
                    //if (wc != EOS)
                    //
                    return(new InstructionLine(position, FunctionIdentifier.SETFunction, opWT.Code, wc, null));
                }

                #endregion

                var idWT = LexicalAnalyzer.ReadFirstIdentifierWord(stream);
                if (idWT != null)
                {
                    var func = GlobalStatic.IdentifierDictionary.GetFunctionIdentifier(idWT.Code);
                    //命令文
                    if (func != null)   //関数文
                    {
                        if (stream.EOS) //引数の無い関数
                        {
                            return(new InstructionLine(position, func, stream));
                        }
                        if (stream.Current != ';' && stream.Current != ' ' && stream.Current != '\t' &&
                            (!Config.SystemAllowFullSpace || stream.Current != ' '))
                        {
                            if (stream.Current == ' ')
                            {
                                errMes = "命令で行が始まっていますが、命令の直後に半角スペース・タブ以外の文字が来ています(この警告はシステムオプション「" +
                                         Config.GetConfigName(ConfigCode.SystemAllowFullSpace) + "」により無視できます)";
                            }
                            else
                            {
                                errMes = "命令で行が始まっていますが、命令の直後に半角スペース・タブ以外の文字が来ています";
                            }
                            goto err;
                        }
                        stream.ShiftNext();
                        return(new InstructionLine(position, func, stream));
                    }
                }
                LexicalAnalyzer.SkipWhiteSpace(stream);
                if (stream.EOS)
                {
                    errMes = "解釈できない行です";
                    goto err;
                }
                //命令行ではない→代入行のはず
                stream.Seek(0, SeekOrigin.Begin);
                var assignOP = OperatorCode.NULL;
                var wc1      = LexicalAnalyzer.Analyse(stream, LexEndWith.Operator, LexAnalyzeFlag.None);
                //if (idWT != null)
                //	wc1.Collection.Insert(0, idWT);
                try
                {
                    assignOP = LexicalAnalyzer.ReadAssignmentOperator(stream);
                }
                catch (CodeEE)
                {
                    errMes = "解釈できない行です";
                    goto err;
                }
                //eramaker互換警告
                //stream.Jump(-1);
                //if ((stream.Current != ' ') && (stream.Current != '\t'))
                //{
                //	errMes = "変数で行が始まっていますが、演算子の直前に半角スペースまたはタブがありません";
                //	goto err;
                //}
                //stream.ShiftNext();


                if (assignOP == OperatorCode.Equal)
                {
                    if (console != null)
                    {
                        ParserMediator.Warn("代入演算子に\"==\"が使われています", position, 0);
                    }
                    //"=="を代入文に使うのは本当はおかしいが結構使われているので仕様にする
                    assignOP = OperatorCode.Assignment;
                }
                return(new InstructionLine(position, FunctionIdentifier.SETFunction, assignOP, wc1, stream));

err:
                return(new InvalidLine(position, errMes));
            }
            catch (CodeEE e)
            {
                SystemSounds.Hand.Play();
                return(new InvalidLine(position, e.Message));
            }
        }
Exemplo n.º 5
0
        public static LogicalLine ParseLabelLine(StringStream stream, ScriptPosition position, EmueraConsole console)
        {
            var isFunction = stream.Current == '@';
            var lineNo     = position.LineNo;
            var labelName  = "";
            var errMes     = "";

            try
            {
                var warnLevel = -1;
                stream.ShiftNext(); //@か$を除去
                var wc = LexicalAnalyzer.Analyse(stream, LexEndWith.EoL, LexAnalyzeFlag.AllowAssignment);
                if (wc.EOL || !(wc.Current is IdentifierWord))
                {
                    errMes = "関数名が不正であるか存在しません";
                    goto err;
                }
                labelName = ((IdentifierWord)wc.Current).Code;
                wc.ShiftNext();
                if (Config.ICVariable)
                {
                    labelName = labelName.ToUpper();
                }
                GlobalStatic.IdentifierDictionary.CheckUserLabelName(ref errMes, ref warnLevel, isFunction, labelName);
                if (warnLevel >= 0)
                {
                    if (warnLevel >= 2)
                    {
                        goto err;
                    }
                    ParserMediator.Warn(errMes, position, warnLevel);
                }
                if (!isFunction) //$ならこの時点で終了
                {
                    if (!wc.EOL)
                    {
                        ParserMediator.Warn("$で始まるラベルに引数が設定されています", position, 1);
                    }
                    return(new GotoLabelLine(position, labelName));
                }


                //labelName = LexicalAnalyzer.ReadString(stream, StrEndWith.LeftParenthesis_Bracket_Comma_Semicolon);
                //labelName = labelName.Trim();
                //if (Config.ICVariable)
                //    labelName = labelName.ToUpper();
                //GlobalStatic.IdentifierDictionary.CheckUserLabelName(ref errMes, ref warnLevel, isFunction, labelName);
                //if(warnLevel >= 0)
                //{
                //    if (warnLevel >= 2)
                //        goto err;
                //    ParserMediator.Warn(errMes, position, warnLevel);
                //}
                //if (!isFunction)//$ならこの時点で終了
                //{
                //    LexicalAnalyzer.SkipWhiteSpace(stream);
                //    if (!stream.EOS)
                //        ParserMediator.Warn("$で始まるラベルに引数が設定されています", position, 1);
                //    return new GotoLabelLine(position, labelName);
                //}

                ////関数名部分に_renameを使えないように変更
                //if (ParserMediator.RenameDic != null && ((stream.ToString().IndexOf("[[") >= 0) && (stream.ToString().IndexOf("]]") >= 0)))
                //{
                //    string line = stream.ToString();
                //    foreach (KeyValuePair<string, string> pair in ParserMediator.RenameDic)
                //        line = line.Replace(pair.Key, pair.Value);
                //    stream = new StringStream(line);
                //}
                //WordCollection wc = null;
                //wc = LexicalAnalyzer.Analyse(stream, LexEndWith.EoL, LexAnalyzeFlag.AllowAssignment);
                if (Program.AnalysisMode)
                {
                    console.PrintC("@" + labelName, false);
                }
                var funclabelLine = new FunctionLabelLine(position, labelName, wc);
                if (IdentifierDictionary.IsEventLabelName(labelName))
                {
                    funclabelLine.IsEvent  = true;
                    funclabelLine.IsSystem = true;
                    funclabelLine.Depth    = 0;
                }
                else if (IdentifierDictionary.IsSystemLabelName(labelName))
                {
                    funclabelLine.IsSystem = true;
                    funclabelLine.Depth    = 0;
                }
                return(funclabelLine);
            }
            catch (CodeEE e)
            {
                errMes = e.Message;
            }
err:
            SystemSounds.Hand.Play();
            if (isFunction)
            {
                if (labelName.Length == 0)
                {
                    labelName = "<Error>";
                }
                return(new InvalidLabelLine(position, labelName, errMes));
            }
            return(new InvalidLine(position, errMes));
        }
Exemplo n.º 6
0
        public static bool ParseSharpLine(FunctionLabelLine label, StringStream st, ScriptPosition position,
                                          List <string> OnlyLabel)
        {
            st.ShiftNext();                                       //'#'を飛ばす
            var token = LexicalAnalyzer.ReadSingleIdentifier(st); //#~自体にはマクロ非適用

            if (Config.ICFunction)
            {
                token = token.ToUpper();
            }
            //#行として不正な行でもAnalyzeに行って引っかかることがあるので、先に存在しない#~は弾いてしまう
            if (token == null || token != "SINGLE" && token != "LATER" && token != "PRI" && token != "ONLY" &&
                token != "FUNCTION" && token != "FUNCTIONS" &&
                token != "LOCALSIZE" && token != "LOCALSSIZE" && token != "DIM" && token != "DIMS")
            {
                ParserMediator.Warn("解釈できない#行です", position, 1);
                return(false);
            }
            try
            {
                var wc = LexicalAnalyzer.Analyse(st, LexEndWith.EoL, LexAnalyzeFlag.AllowAssignment);
                switch (token)
                {
                case "SINGLE":
                    if (label.IsMethod)
                    {
                        ParserMediator.Warn("式中関数では#SINGLEは機能しません", position, 1);
                        break;
                    }
                    else if (!label.IsEvent)
                    {
                        ParserMediator.Warn("イベント関数以外では#SINGLEは機能しません", position, 1);
                        break;
                    }
                    else if (label.IsSingle)
                    {
                        ParserMediator.Warn("#SINGLEが重複して使われています", position, 1);
                        break;
                    }
                    else if (label.IsOnly)
                    {
                        ParserMediator.Warn("#ONLYが指定されたイベント関数では#SINGLEは機能しません", position, 1);
                        break;
                    }
                    label.IsSingle = true;
                    break;

                case "LATER":
                    if (label.IsMethod)
                    {
                        ParserMediator.Warn("式中関数では#LATERは機能しません", position, 1);
                        break;
                    }
                    else if (!label.IsEvent)
                    {
                        ParserMediator.Warn("イベント関数以外では#LATERは機能しません", position, 1);
                        break;
                    }
                    else if (label.IsLater)
                    {
                        ParserMediator.Warn("#LATERが重複して使われています", position, 1);
                        break;
                    }
                    else if (label.IsOnly)
                    {
                        ParserMediator.Warn("#ONLYが指定されたイベント関数では#LATERは機能しません", position, 1);
                        break;
                    }
                    else if (label.IsPri)
                    {
                        ParserMediator.Warn("#PRIと#LATERが重複して使われています(この関数は2度呼ばれます)", position, 1);
                    }
                    label.IsLater = true;
                    break;

                case "PRI":
                    if (label.IsMethod)
                    {
                        ParserMediator.Warn("式中関数では#PRIは機能しません", position, 1);
                        break;
                    }
                    else if (!label.IsEvent)
                    {
                        ParserMediator.Warn("イベント関数以外では#PRIは機能しません", position, 1);
                        break;
                    }
                    else if (label.IsPri)
                    {
                        ParserMediator.Warn("#PRIが重複して使われています", position, 1);
                        break;
                    }
                    else if (label.IsOnly)
                    {
                        ParserMediator.Warn("#ONLYが指定されたイベント関数では#PRIは機能しません", position, 1);
                        break;
                    }
                    else if (label.IsLater)
                    {
                        ParserMediator.Warn("#PRIと#LATERが重複して使われています(この関数は2度呼ばれます)", position, 1);
                    }
                    label.IsPri = true;
                    break;

                case "ONLY":
                    if (label.IsMethod)
                    {
                        ParserMediator.Warn("式中関数では#ONLYは機能しません", position, 1);
                        break;
                    }
                    else if (!label.IsEvent)
                    {
                        ParserMediator.Warn("イベント関数以外では#ONLYは機能しません", position, 1);
                        break;
                    }
                    else if (label.IsOnly)
                    {
                        ParserMediator.Warn("#ONLYが重複して使われています", position, 1);
                        break;
                    }
                    else if (OnlyLabel.Contains(label.LabelName))
                    {
                        ParserMediator.Warn("このイベント関数\"@" + label.LabelName + "\"にはすでに#ONLYが宣言されています(この関数は実行されません)",
                                            position, 1);
                    }
                    OnlyLabel.Add(label.LabelName);
                    label.IsOnly = true;
                    if (label.IsPri)
                    {
                        ParserMediator.Warn("このイベント関数には#PRIが宣言されていますが無視されます", position, 1);
                        label.IsPri = false;
                    }
                    if (label.IsLater)
                    {
                        ParserMediator.Warn("このイベント関数には#LATERが宣言されていますが無視されます", position, 1);
                        label.IsLater = false;
                    }
                    if (label.IsSingle)
                    {
                        ParserMediator.Warn("このイベント関数には#SINGLEが宣言されていますが無視されます", position, 1);
                        label.IsSingle = false;
                    }
                    break;

                case "FUNCTION":
                case "FUNCTIONS":
                    if (!string.IsNullOrEmpty(label.LabelName) && char.IsDigit(label.LabelName[0]))
                    {
                        ParserMediator.Warn("#" + token + "属性は関数名が数字で始まる関数には指定できません", position, 1);
                        label.IsError = true;
                        label.ErrMes  = "関数名が数字で始まっています";
                        break;
                    }
                    if (label.IsMethod)
                    {
                        if (label.MethodType == typeof(long) && token == "FUNCTION" ||
                            label.MethodType == typeof(string) && token == "FUNCTIONS")
                        {
                            ParserMediator.Warn("関数" + label.LabelName + "にはすでに#" + token + "が宣言されています(この行は無視されます)",
                                                position, 1);
                            return(false);
                        }
                        if (label.MethodType == typeof(long) && token == "FUNCTIONS")
                        {
                            ParserMediator.Warn("関数" + label.LabelName + "にはすでに#FUNCTIONが宣言されています", position, 2);
                        }
                        else if (label.MethodType == typeof(string) && token == "FUNCTION")
                        {
                            ParserMediator.Warn("関数" + label.LabelName + "にはすでに#FUNCTIONSが宣言されています", position, 2);
                        }
                        return(false);
                    }
                    if (label.Depth == 0)
                    {
                        ParserMediator.Warn("システム関数に#" + token + "が指定されています", position, 2);
                        return(false);
                    }
                    label.IsMethod = true;
                    label.Depth    = 0;
                    if (token == "FUNCTIONS")
                    {
                        label.MethodType = typeof(string);
                    }
                    else
                    {
                        label.MethodType = typeof(long);
                    }
                    if (label.IsPri)
                    {
                        ParserMediator.Warn("式中関数では#PRIは機能しません", position, 1);
                        label.IsPri = false;
                    }
                    if (label.IsLater)
                    {
                        ParserMediator.Warn("式中関数では#LATERは機能しません", position, 1);
                        label.IsLater = false;
                    }
                    if (label.IsSingle)
                    {
                        ParserMediator.Warn("式中関数では#SINGLEは機能しません", position, 1);
                        label.IsSingle = false;
                    }
                    if (label.IsOnly)
                    {
                        ParserMediator.Warn("式中関数では#ONLYは機能しません", position, 1);
                        label.IsOnly = false;
                    }
                    break;

                case "LOCALSIZE":
                case "LOCALSSIZE":
                {
                    if (wc.EOL)
                    {
                        ParserMediator.Warn("#" + token + "の後に有効な数値が指定されていません", position, 2);
                        break;
                    }
                    //イベント関数では指定しても無視される
                    if (label.IsEvent)
                    {
                        ParserMediator.Warn(
                            "イベント関数では#" + token + "による" + token.Substring(0, token.Length - 4) + "のサイズ指定は無視されます",
                            position, 1);
                        break;
                    }
                    var arg      = ExpressionParser.ReduceIntegerTerm(wc, TermEndWith.EoL);
                    var sizeTerm = arg.Restructure(null) as SingleTerm;
                    if (sizeTerm == null || sizeTerm.GetOperandType() != typeof(long))
                    {
                        ParserMediator.Warn("#" + token + "の後に有効な定数式が指定されていません", position, 2);
                        break;
                    }
                    if (sizeTerm.Int <= 0)
                    {
                        ParserMediator.Warn("#" + token + "に0以下の値(" + sizeTerm.Int + ")が与えられました。設定は無視されます",
                                            position, 1);
                        break;
                    }
                    if (sizeTerm.Int >= int.MaxValue)
                    {
                        ParserMediator.Warn("#" + token + "に大きすぎる値(" + sizeTerm.Int + ")が与えられました。設定は無視されます",
                                            position, 1);
                        break;
                    }
                    var size = (int)sizeTerm.Int;
                    if (token == "LOCALSIZE")
                    {
                        if (GlobalStatic.IdentifierDictionary.getLocalIsForbid("LOCAL"))
                        {
                            ParserMediator.Warn("#" + token + "が指定されていますが変数LOCALは使用禁止されています", position, 2);
                            break;
                        }
                        if (label.LocalLength > 0)
                        {
                            ParserMediator.Warn("この関数にはすでに#LOCALSIZEが定義されています。(以前の定義は無視されます)", position, 1);
                        }
                        label.LocalLength = size;
                    }
                    else
                    {
                        if (GlobalStatic.IdentifierDictionary.getLocalIsForbid("LOCALS"))
                        {
                            ParserMediator.Warn("#" + token + "が指定されていますが変数LOCALSは使用禁止されています", position, 2);
                            break;
                        }
                        if (label.LocalsLength > 0)
                        {
                            ParserMediator.Warn("この関数にはすでに#LOCALSSIZEが定義されています。(以前の定義は無視されます)", position, 1);
                        }
                        label.LocalsLength = size;
                    }
                }
                break;

                case "DIM":
                case "DIMS":
                {
                    var data = UserDefinedVariableData.Create(wc, token == "DIMS", true, position);
                    if (!label.AddPrivateVariable(data))
                    {
                        ParserMediator.Warn("変数名" + data.Name + "は既に使用されています", position, 2);
                        return(false);
                    }
                    break;
                }

                default:
                    ParserMediator.Warn("解釈できない#行です", position, 1);
                    break;
                }
                if (!wc.EOL)
                {
                    ParserMediator.Warn("#の識別子の後に余分な文字があります", position, 1);
                }
            }
            catch (Exception e)
            {
                ParserMediator.Warn(e.Message, position, 2);
                goto err;
            }
            return(true);

err:
            return(false);
        }
Exemplo n.º 7
0
        //#define FOO (~~)     id to wc
        //#define BAR($1) (~~)     idwithargs to wc(replaced)
        //#diseble FOOBAR
        //#dim piyo, i
        //#dims puyo, j
        //static List<string> keywordsList = new List<string>();

        private void analyzeSharpDefine(StringStream st, ScriptPosition position)
        {
            //LexicalAnalyzer.SkipWhiteSpace(st);呼び出し前に行う。
            var srcID = LexicalAnalyzer.ReadSingleIdentifier(st);

            if (srcID == null)
            {
                throw new CodeEE("置換元の識別子がありません", position);
            }
            if (Config.ICVariable)
            {
                srcID = srcID.ToUpper();
            }

            //ここで名称重複判定しないと、大変なことになる
            var errMes   = "";
            var errLevel = -1;

            idDic.CheckUserMacroName(ref errMes, ref errLevel, srcID);
            if (errLevel >= 0)
            {
                ParserMediator.Warn(errMes, position, errLevel);
                if (errLevel >= 2)
                {
                    noError = false;
                    return;
                }
            }

            var hasArg = st.Current == '('; //引数を指定する場合には直後に(が続いていなければならない。ホワイトスペースも禁止。
            //1808a3 代入演算子許可(関数宣言用)
            var wc = LexicalAnalyzer.Analyse(st, LexEndWith.EoL, LexAnalyzeFlag.AllowAssignment);

            if (wc.EOL)
            {
                //throw new CodeEE("置換先の式がありません", position);
                //1808a3 空マクロの許可
                var nullmac = new DefineMacro(srcID, new WordCollection(), 0);
                idDic.AddMacro(nullmac);
                return;
            }

            var argID = new List <string>();

            if (hasArg)         //関数型マクロの引数解析
            {
                wc.ShiftNext(); //'('を読み飛ばす
                if (wc.Current.Type == ')')
                {
                    throw new CodeEE("関数型マクロの引数を0個にすることはできません", position);
                }
                while (!wc.EOL)
                {
                    var word = wc.Current as IdentifierWord;
                    if (word == null)
                    {
                        throw new CodeEE("置換元の引数指定の書式が間違っています", position);
                    }
                    word.SetIsMacro();
                    var id = word.Code;
                    if (argID.Contains(id))
                    {
                        throw new CodeEE("置換元の引数に同じ文字が2回以上使われています", position);
                    }
                    argID.Add(id);
                    wc.ShiftNext();
                    if (wc.Current.Type == ',')
                    {
                        wc.ShiftNext();
                        continue;
                    }
                    if (wc.Current.Type == ')')
                    {
                        break;
                    }
                    throw new CodeEE("置換元の引数指定の書式が間違っています", position);
                }
                if (wc.EOL)
                {
                    throw new CodeEE("')'が閉じられていません", position);
                }

                wc.ShiftNext();
            }
            if (wc.EOL)
            {
                throw new CodeEE("置換先の式がありません", position);
            }
            var destWc = new WordCollection();

            while (!wc.EOL)
            {
                destWc.Add(wc.Current);
                wc.ShiftNext();
            }
            if (hasArg) //関数型マクロの引数セット
            {
                while (!destWc.EOL)
                {
                    var word = destWc.Current as IdentifierWord;
                    if (word == null)
                    {
                        destWc.ShiftNext();
                        continue;
                    }
                    for (var i = 0; i < argID.Count; i++)
                    {
                        if (string.Equals(word.Code, argID[i], Config.SCVariable))
                        {
                            destWc.Remove();
                            destWc.Insert(new MacroWord(i));
                            break;
                        }
                    }
                    destWc.ShiftNext();
                }
                destWc.Pointer = 0;
            }
            if (hasArg) //1808a3 関数型マクロの封印
            {
                throw new CodeEE("関数型マクロは宣言できません", position);
            }
            var mac = new DefineMacro(srcID, destWc, argID.Count);

            idDic.AddMacro(mac);
        }
Exemplo n.º 8
0
        private static AConsoleDisplayPart tagAnalyze(HtmlAnalzeState state, StringStream st)
        {
            bool   endTag = (st.Current == '/');
            string tag;

            if (endTag)
            {
                st.ShiftNext();
                int found = st.Find('>');
                if (found < 0)
                {
                    st.CurrentPosition = st.RowString.Length;
                    return(null);                   //戻り先でエラーを出す
                }
                tag = st.Substring(st.CurrentPosition, found).Trim();
                st.CurrentPosition += found;
                FontStyle endStyle = FontStyle.Strikeout;
                switch (tag.ToLower())
                {
                case "b": endStyle = FontStyle.Bold; goto case "s";

                case "i": endStyle = FontStyle.Italic; goto case "s";

                case "u": endStyle = FontStyle.Underline; goto case "s";

                case "s":
                    if ((state.FontStyle & endStyle) == FontStyle.Regular)
                    {
                        throw new CodeEE("</" + tag + ">の前に<" + tag + ">がありません");
                    }
                    state.FontStyle ^= endStyle;
                    return(null);

                case "p":
                    if ((!state.FlagP) || (state.FlagPClosed))
                    {
                        throw new CodeEE("</p>の前に<p>がありません");
                    }
                    state.FlagPClosed = true;
                    return(null);

                case "nobr":
                    if ((!state.FlagNobr) || (state.FlagNobrClosed))
                    {
                        throw new CodeEE("</nobr>の前に<nobr>がありません");
                    }
                    state.FlagNobrClosed = true;
                    return(null);

                case "font":
                    if (state.FonttagList.Count == 0)
                    {
                        throw new CodeEE("</font>の前に<font>がありません");
                    }
                    state.FonttagList.RemoveAt(state.FonttagList.Count - 1);
                    return(null);

                case "button":
                    if (state.CurrentButtonTag == null || !state.CurrentButtonTag.IsButtonTag)
                    {
                        throw new CodeEE("</button>の前に<button>がありません");
                    }
                    state.CurrentButtonTag = null;
                    state.FlagButton       = true;
                    return(null);

                case "nonbutton":
                    if (state.CurrentButtonTag == null || state.CurrentButtonTag.IsButtonTag)
                    {
                        throw new CodeEE("</nonbutton>の前に<nonbutton>がありません");
                    }
                    state.CurrentButtonTag = null;
                    state.FlagButton       = true;
                    return(null);

                default:
                    throw new CodeEE("終了タグ</" + tag + ">は解釈できません");
                }
                //goto error;
            }
            //以降は開始タグ

            bool           tempUseMacro = LexicalAnalyzer.UseMacro;
            WordCollection wc           = null;

            try
            {
                LexicalAnalyzer.UseMacro = false;                //一時的にマクロ展開をやめる
                tag = LexicalAnalyzer.ReadSingleIdentifier(st);
                LexicalAnalyzer.SkipWhiteSpace(st);
                if (st.Current != '>')
                {
                    wc = LexicalAnalyzer.Analyse(st, LexEndWith.GreaterThan, LexAnalyzeFlag.AllowAssignment | LexAnalyzeFlag.AllowSingleQuotationStr);
                }
            }
            finally
            {
                LexicalAnalyzer.UseMacro = tempUseMacro;
            }
            if (string.IsNullOrEmpty(tag))
            {
                goto error;
            }
            IdentifierWord word;
            FontStyle      newStyle = FontStyle.Strikeout;

            switch (tag.ToLower())
            {
            case "b": newStyle = FontStyle.Bold; goto case "s";

            case "i": newStyle = FontStyle.Italic; goto case "s";

            case "u": newStyle = FontStyle.Underline; goto case "s";

            case "s":
                if (wc != null)
                {
                    throw new CodeEE("<" + tag + ">タグにに属性が設定されています");
                }
                if ((state.FontStyle & newStyle) != FontStyle.Regular)
                {
                    throw new CodeEE("<" + tag + ">が二重に使われています");
                }
                state.FontStyle |= newStyle;
                return(null);

            case "br":
                if (wc != null)
                {
                    throw new CodeEE("<" + tag + ">タグにに属性が設定されています");
                }
                state.FlagBr = true;
                return(null);

            case "nobr":
                if (wc != null)
                {
                    throw new CodeEE("<" + tag + ">タグに属性が設定されています");
                }
                if (!state.LineHead)
                {
                    throw new CodeEE("<nobr>が行頭以外で使われています");
                }
                if (state.FlagNobr)
                {
                    throw new CodeEE("<nobr>が2度以上使われています");
                }
                state.FlagNobr = true;
                return(null);

            case "p":
            {
                if (wc == null)
                {
                    throw new CodeEE("<" + tag + ">タグに属性が設定されていません");
                }
                if (!state.LineHead)
                {
                    throw new CodeEE("<p>が行頭以外で使われています");
                }
                if (state.FlagNobr)
                {
                    throw new CodeEE("<p>が2度以上使われています");
                }
                word = wc.Current as IdentifierWord;
                wc.ShiftNext();
                OperatorWord op = wc.Current as OperatorWord;
                wc.ShiftNext();
                LiteralStringWord attr = wc.Current as LiteralStringWord;
                wc.ShiftNext();
                if (!wc.EOL || word == null || op == null || op.Code != OperatorCode.Assignment || attr == null)
                {
                    goto error;
                }
                if (!word.Code.Equals("align", StringComparison.OrdinalIgnoreCase))
                {
                    throw new CodeEE("<p>タグの属性名" + word.Code + "は解釈できません");
                }
                string attrValue = Unescape(attr.Str);
                switch (attrValue.ToLower())
                {
                case "left":
                    state.Alignment = DisplayLineAlignment.LEFT;
                    break;

                case "center":
                    state.Alignment = DisplayLineAlignment.CENTER;
                    break;

                case "right":
                    state.Alignment = DisplayLineAlignment.RIGHT;
                    break;

                default:
                    throw new CodeEE("属性値" + attr.Str + "は解釈できません");
                }
                state.FlagP = true;
                return(null);
            }

            case "img":
            {
                if (wc == null)
                {
                    throw new CodeEE("<" + tag + ">タグに属性が設定されていません");
                }
                string attrValue = null;
                string src       = null;
                string srcb      = null;
                int    height    = 0;
                int    width     = 0;
                int    ypos      = 0;
                while (wc != null && !wc.EOL)
                {
                    word = wc.Current as IdentifierWord;
                    wc.ShiftNext();
                    OperatorWord op = wc.Current as OperatorWord;
                    wc.ShiftNext();
                    LiteralStringWord attr = wc.Current as LiteralStringWord;
                    wc.ShiftNext();
                    if (word == null || op == null || op.Code != OperatorCode.Assignment || attr == null)
                    {
                        goto error;
                    }
                    attrValue = Unescape(attr.Str);
                    if (word.Code.Equals("src", StringComparison.OrdinalIgnoreCase))
                    {
                        if (src != null)
                        {
                            throw new CodeEE("<" + tag + ">タグに" + word.Code + "属性が2度以上指定されています");
                        }
                        src = attrValue;
                    }
                    else if (word.Code.Equals("srcb", StringComparison.OrdinalIgnoreCase))
                    {
                        if (srcb != null)
                        {
                            throw new CodeEE("<" + tag + ">タグに" + word.Code + "属性が2度以上指定されています");
                        }
                        srcb = attrValue;
                    }
                    else if (word.Code.Equals("height", StringComparison.OrdinalIgnoreCase))
                    {
                        if (height != 0)
                        {
                            throw new CodeEE("<" + tag + ">タグに" + word.Code + "属性が2度以上指定されています");
                        }
                        if (!int.TryParse(attrValue, out height))
                        {
                            throw new CodeEE("<" + tag + ">タグのheight属性の属性値が数値として解釈できません");
                        }
                    }
                    else if (word.Code.Equals("width", StringComparison.OrdinalIgnoreCase))
                    {
                        if (width != 0)
                        {
                            throw new CodeEE("<" + tag + ">タグに" + word.Code + "属性が2度以上指定されています");
                        }
                        if (!int.TryParse(attrValue, out width))
                        {
                            throw new CodeEE("<" + tag + ">タグのwidth属性の属性値が数値として解釈できません");
                        }
                    }
                    else if (word.Code.Equals("ypos", StringComparison.OrdinalIgnoreCase))
                    {
                        if (ypos != 0)
                        {
                            throw new CodeEE("<" + tag + ">タグに" + word.Code + "属性が2度以上指定されています");
                        }
                        if (!int.TryParse(attrValue, out ypos))
                        {
                            throw new CodeEE("<" + tag + ">タグのypos属性の属性値が数値として解釈できません");
                        }
                    }
                    else
                    {
                        throw new CodeEE("<" + tag + ">タグの属性名" + word.Code + "は解釈できません");
                    }
                }
                if (src == null)
                {
                    throw new CodeEE("<" + tag + ">タグにsrc属性が設定されていません");
                }
                return(new ConsoleImagePart(src, srcb, height, width, ypos));
            }

            case "shape":
            {
                if (wc == null)
                {
                    throw new CodeEE("<" + tag + ">タグに属性が設定されていません");
                }
                int[]  param  = null;
                string type   = null;
                int    color  = -1;
                int    bcolor = -1;
                while (!wc.EOL)
                {
                    word = wc.Current as IdentifierWord;
                    wc.ShiftNext();
                    OperatorWord op = wc.Current as OperatorWord;
                    wc.ShiftNext();
                    LiteralStringWord attr = wc.Current as LiteralStringWord;
                    wc.ShiftNext();
                    if (word == null || op == null || op.Code != OperatorCode.Assignment || attr == null)
                    {
                        goto error;
                    }
                    string attrValue = Unescape(attr.Str);
                    switch (word.Code.ToLower())
                    {
                    case "color":
                        if (color >= 0)
                        {
                            throw new CodeEE("<" + tag + ">タグに" + word.Code + "属性が2度以上指定されています");
                        }
                        color = stringToColorInt32(attrValue);
                        break;

                    case "bcolor":
                        if (bcolor >= 0)
                        {
                            throw new CodeEE("<" + tag + ">タグに" + word.Code + "属性が2度以上指定されています");
                        }
                        bcolor = stringToColorInt32(attrValue);
                        break;

                    case "type":
                        if (type != null)
                        {
                            throw new CodeEE("<" + tag + ">タグに" + word.Code + "属性が2度以上指定されています");
                        }
                        type = attrValue;
                        break;

                    case "param":
                        if (param != null)
                        {
                            throw new CodeEE("<" + tag + ">タグに" + word.Code + "属性が2度以上指定されています");
                        }
                        {
                            string[] tokens = attrValue.Split(',');
                            param = new int[tokens.Length];
                            for (int i = 0; i < tokens.Length; i++)
                            {
                                if (!int.TryParse(tokens[i], out param[i]))
                                {
                                    throw new CodeEE("<" + tag + ">タグの" + word.Code + "属性の属性値が数値として解釈できません");
                                }
                            }
                            break;
                        }

                    default:
                        throw new CodeEE("<" + tag + ">タグの属性名" + word.Code + "は解釈できません");
                    }
                }
                if (param == null)
                {
                    throw new CodeEE("<" + tag + ">タグにparam属性が設定されていません");
                }
                if (type == null)
                {
                    throw new CodeEE("<" + tag + ">タグにtype属性が設定されていません");
                }
                Color c = Config.ForeColor;
                Color b = Config.FocusColor;
                if (color >= 0)
                {
                    c = Color.FromArgb(color >> 16, (color >> 8) & 0xFF, color & 0xFF);
                }
                if (bcolor >= 0)
                {
                    b = Color.FromArgb(bcolor >> 16, (bcolor >> 8) & 0xFF, bcolor & 0xFF);
                }
                return(ConsoleShapePart.CreateShape(type, param, c, b, color >= 0));
            }

            case "button":
            case "nonbutton":
            {
                if (state.CurrentButtonTag != null)
                {
                    throw new CodeEE("<button>又は<nonbutton>が入れ子にされています");
                }
                HtmlAnalzeStateButtonTag buttonTag = new HtmlAnalzeStateButtonTag();
                bool   isButton  = tag.ToLower() == "button";
                string attrValue = null;
                string value     = null;
                //if (wc == null)
                //	throw new CodeEE("<" + tag + ">タグに属性が設定されていません");
                while (wc != null && !wc.EOL)
                {
                    word = wc.Current as IdentifierWord;
                    wc.ShiftNext();
                    OperatorWord op = wc.Current as OperatorWord;
                    wc.ShiftNext();
                    LiteralStringWord attr = wc.Current as LiteralStringWord;
                    wc.ShiftNext();
                    if (word == null || op == null || op.Code != OperatorCode.Assignment || attr == null)
                    {
                        goto error;
                    }
                    attrValue = Unescape(attr.Str);
                    if (word.Code.Equals("value", StringComparison.OrdinalIgnoreCase))
                    {
                        if (!isButton)
                        {
                            throw new CodeEE("<" + tag + ">タグにvalue属性が設定されています");
                        }
                        if (value != null)
                        {
                            throw new CodeEE("<" + tag + ">タグに" + word.Code + "属性が2度以上指定されています");
                        }
                        value = attrValue;
                    }
                    else if (word.Code.Equals("title", StringComparison.OrdinalIgnoreCase))
                    {
                        if (buttonTag.ButtonTitle != null)
                        {
                            throw new CodeEE("<" + tag + ">タグに" + word.Code + "属性が2度以上指定されています");
                        }
                        buttonTag.ButtonTitle = attrValue;
                    }
                    else if (word.Code.Equals("pos", StringComparison.OrdinalIgnoreCase))
                    {
                        //throw new NotImplCodeEE();
                        int pos = 0;
                        if (buttonTag.PointXisLocked)
                        {
                            throw new CodeEE("<" + tag + ">タグに" + word.Code + "属性が2度以上指定されています");
                        }
                        if (!int.TryParse(attrValue, out pos))
                        {
                            throw new CodeEE("<" + tag + ">タグのpos属性の属性値が数値として解釈できません");
                        }
                        buttonTag.PointX         = pos;
                        buttonTag.PointXisLocked = true;
                    }
                    else
                    {
                        throw new CodeEE("<" + tag + ">タグの属性名" + word.Code + "は解釈できません");
                    }
                }
                if (isButton)
                {
                    //if (value == null)
                    //	throw new CodeEE("<" + tag + ">タグにvalue属性が設定されていません");
                    int intValue = 0;
                    buttonTag.ButtonIsInteger = (int.TryParse(value, out intValue));
                    buttonTag.ButtonValueInt  = intValue;
                    buttonTag.ButtonValueStr  = value;
                }
                buttonTag.IsButton     = value != null;
                buttonTag.IsButtonTag  = isButton;
                state.CurrentButtonTag = buttonTag;
                state.FlagButton       = true;
                return(null);
            }

            case "font":
            {
                if (wc == null)
                {
                    throw new CodeEE("<" + tag + ">タグに属性が設定されていません");
                }
                HtmlAnalzeStateFontTag font = new HtmlAnalzeStateFontTag();
                while (!wc.EOL)
                {
                    word = wc.Current as IdentifierWord;
                    wc.ShiftNext();
                    OperatorWord op = wc.Current as OperatorWord;
                    wc.ShiftNext();
                    LiteralStringWord attr = wc.Current as LiteralStringWord;
                    wc.ShiftNext();
                    if (word == null || op == null || op.Code != OperatorCode.Assignment || attr == null)
                    {
                        goto error;
                    }
                    string attrValue = Unescape(attr.Str);
                    switch (word.Code.ToLower())
                    {
                    case "color":
                        if (font.Color >= 0)
                        {
                            throw new CodeEE("<" + tag + ">タグに" + word.Code + "属性が2度以上指定されています");
                        }
                        font.Color = stringToColorInt32(attrValue);
                        break;

                    case "bcolor":
                        if (font.BColor >= 0)
                        {
                            throw new CodeEE("<" + tag + ">タグに" + word.Code + "属性が2度以上指定されています");
                        }
                        font.BColor = stringToColorInt32(attrValue);
                        break;

                    case "face":
                        if (font.FontName != null)
                        {
                            throw new CodeEE("<" + tag + ">タグに" + word.Code + "属性が2度以上指定されています");
                        }
                        font.FontName = attrValue;
                        break;

                    //case "pos":
                    //	{
                    //		//throw new NotImplCodeEE();
                    //		if (font.PointXisLocked)
                    //			throw new CodeEE("<" + tag + ">タグに" + word.Code + "属性が2度以上指定されています");
                    //		int pos = 0;
                    //		if (!int.TryParse(attrValue, out pos))
                    //			throw new CodeEE("<font>タグのpos属性の属性値が数値として解釈できません");
                    //		font.PointX = pos;
                    //		font.PointXisLocked = true;
                    //		break;
                    //	}
                    default:
                        throw new CodeEE("<" + tag + ">タグの属性名" + word.Code + "は解釈できません");
                    }
                }
                //他のfontタグの内側であるなら未設定項目については外側のfontタグの設定を受け継ぐ(posは除く)
                if (state.FonttagList.Count > 0)
                {
                    HtmlAnalzeStateFontTag oldFont = state.FonttagList[state.FonttagList.Count - 1];
                    if (font.Color < 0)
                    {
                        font.Color = oldFont.Color;
                    }
                    if (font.BColor < 0)
                    {
                        font.BColor = oldFont.BColor;
                    }
                    if (font.FontName == null)
                    {
                        font.FontName = oldFont.FontName;
                    }
                }
                state.FonttagList.Add(font);
                return(null);
            }

            default:
                goto error;
            }


error:
            throw new CodeEE("html文字列\"" + st.RowString + "\"のタグ解析中にエラーが発生しました");
        }
Exemplo n.º 9
0
        private bool loadHeaderFile(string filepath, string filename)
        {
            StringStream   st       = null;
            ScriptPosition position = null;
            //EraStreamReader eReader = new EraStreamReader(false);
            //1815修正 _rename.csvの適用
            //eramakerEXの仕様的には.ERHに適用するのはおかしいけど、もうEmueraの仕様になっちゃってるのでしかたないか
            EraStreamReader eReader = new EraStreamReader(true);

            if (!eReader.Open(filepath, filename))
            {
                throw new CodeEE(eReader.Filename + "のオープンに失敗しました");
                //return false;
            }
            try
            {
                while ((st = eReader.ReadEnabledLine()) != null)
                {
                    if (!noError)
                    {
                        return(false);
                    }
                    position = new ScriptPosition(filename, eReader.LineNo, st.RowString);
                    LexicalAnalyzer.SkipWhiteSpace(st);
                    if (st.Current != '#')
                    {
                        throw new CodeEE("ヘッダーの中に#で始まらない行があります", position);
                    }
                    st.ShiftNext();
                    string sharpID = LexicalAnalyzer.ReadSingleIdentifier(st);
                    if (sharpID == null)
                    {
                        ParserMediator.Warn("解釈できない#行です", position, 1);
                        return(false);
                    }
                    if (Config.ICFunction)
                    {
                        sharpID = sharpID.ToUpper();
                    }
                    LexicalAnalyzer.SkipWhiteSpace(st);
                    switch (sharpID)
                    {
                    case "DEFINE":
                        analyzeSharpDefine(st, position);
                        break;

                    case "FUNCTION":
                    case "FUNCTIONS":
                        analyzeSharpFunction(st, position, sharpID == "FUNCTIONS");
                        break;

                    case "DIM":
                    case "DIMS":
                        //1822 #DIMは保留しておいて後でまとめてやる
                    {
                        WordCollection wc = LexicalAnalyzer.Analyse(st, LexEndWith.EoL, LexAnalyzeFlag.AllowAssignment);
                        dimlines.Enqueue(new DimLineWC(wc, sharpID == "DIMS", false, position));
                    }
                        //analyzeSharpDim(st, position, sharpID == "DIMS");
                        break;

                    default:
                        throw new CodeEE("#" + sharpID + "は解釈できないプリプロセッサです", position);
                    }
                }
            }
            catch (CodeEE e)
            {
                if (e.Position != null)
                {
                    position = e.Position;
                }
                ParserMediator.Warn(e.Message, position, 2);
                return(false);
            }
            finally
            {
                eReader.Close();
            }
            return(true);
        }