ZhiYeJianKang_PeiXun/cyqdata-master/Json/JsonImplement/CharState.cs

415 lines
17 KiB
C#
Raw Permalink Normal View History

2025-02-20 15:41:53 +08:00
using System;
using System.Collections.Generic;
using System.Text;
namespace CYQ.Data.Json
{
/// <summary>
/// 字符状态
/// </summary>
internal class CharState
{
internal char lastKeywordChar = ' ';
internal char lastChar = ' ';
/// <summary>
/// 是否格式格式【true属性必须双引号false属性可以单引号和无引号。】
/// </summary>
internal bool isStrictMode = false;
public CharState(bool isStrictMode)
{
this.isStrictMode = isStrictMode;
}
internal bool jsonStart = false;//以 "{"开始了...
internal bool setDicValue = false;// 可以设置字典值了。
internal bool escapeChar = false;//以"\"转义符号开始了
/// <summary>
/// 数组开始【仅第一开头才算】值嵌套的以【childrenStart】来标识。
/// </summary>
internal bool arrayStart = false;//以"[" 符号开始了
internal bool childrenStart = false;//子级嵌套开始了。
/// <summary>
/// 【-1 未初始化】【0取名阶段】【1 取值阶段】
/// </summary>
internal int keyValueState = -1;
/// <summary>
/// 【-2 已结束】【-1 未初始化】【0 未开始】【1 无引号开始】【2 单引号开始】【3 双引号开始】
/// </summary>
internal int keyStart = -1;
/// <summary>
/// 【-2 已结束】【-1 未初始化】【0 未开始】【1 无引号开始】【2 单引号开始】【3 双引号开始】
/// </summary>
internal int valueStart = -1;
internal bool isError = false;//是否语法错误。
internal void CheckIsError(char c)//只当成一级处理因为GetLength会递归到每一个子项处理
{
switch (c)
{
case '\r':
case '\n':
case '\t':
return;
case '{'://[{ "[{A}]":[{"[{B}]":3,"m":"C"}]}]
isError = jsonStart && keyValueState == 0;//重复开始错误 同时不是值处理。
break;
case '}':
isError = !jsonStart || (keyStart > 0 && keyValueState == 0);//重复结束错误 或者 提前结束。
if (!isError && isStrictMode)
{
isError = !((keyStart == 3 && keyValueState == 0) || (valueStart != 2 && keyValueState == 1) || valueStart == -2 || (jsonStart && keyStart == -1));
}
break;
case '[':
isError = arrayStart && keyValueState == 0;//重复开始错误
break;
case ']':
isError = (!arrayStart && valueStart != 3 && keyStart != 3) || (keyValueState == 1 && valueStart == 0);//重复开始错误[{},]1,0 正常:[111,222] 1,1 [111,"22"] 1,-2
break;
case '"':
isError = !jsonStart && !arrayStart;//未开始Json同时也未开始数组。
break;
case '\'':
isError = (!jsonStart && !arrayStart);//未开始Json
if (!isError && isStrictMode)
{
isError = !((keyStart == 3 && keyValueState == 0) || (valueStart == 3 && keyValueState == 1));
}
break;
case ':':
isError = (!jsonStart && !arrayStart) || (jsonStart && keyStart < 2 && valueStart < 2 && keyValueState == 1);//未开始Json 同时 只能处理在取值之前。
break;
case ',':
isError = (!jsonStart && !arrayStart)
|| (!jsonStart && arrayStart && keyValueState == -1) //[,111]
|| (jsonStart && keyStart < 2 && valueStart < 2 && keyValueState == 0);//未开始Json 同时 只能处理在取值之后。
break;
//case 't'://true
//case 'f'://false
// break;
default: //值开头。。
isError = (!jsonStart && !arrayStart) || (keyStart == 0 && valueStart == 0 && keyValueState == 0);//
if (!isError && keyStart < 2)
{
//if ((jsonStart && !arrayStart) && state != 1)
if (jsonStart && keyValueState <= 0)//取名阶段
{
//不是引号开头的,只允许字母 {aaa:1}
isError = isStrictMode || (c < 65 || (c > 90 && c < 97) || c > 122);
}
else if (!jsonStart && arrayStart && valueStart < 2)//
{
switch (c)
{
case ' ':
case 'n'://null
case 'u':
case 'l':
case 't'://true
case 'r':
case 'e':
case 'f'://false
case 'a':
case 's':
break;
default:
//不是引号开头的,只允许数字[1] 空格、null,true,false
isError = c < 48 || c > 57;
break;
}
}
}
if (!isError && isStrictMode)
{
if (jsonStart && valueStart == 1)//检测值value:true 或value:false
{
switch (c)
{
case 'r'://true
isError = lastChar != 't';
break;
case 'u'://true,null
isError = !((lastKeywordChar == 't' && lastChar == 'r') || (lastKeywordChar == 'n' && lastChar == 'n'));
break;
case 'e'://true
isError = !((lastKeywordChar == 't' && lastChar == 'u') || (lastKeywordChar == 'f' && lastChar == 's'));
break;
case 'a'://false
isError = lastChar != 'f';
break;
case 'l'://false,null
isError = !((lastKeywordChar == 'f' && lastChar == 'a') || (lastKeywordChar == 'n' && (lastChar == 'u' || lastChar == 'l')));
if (!isError && lastKeywordChar == 'n' && lastChar == 'l')
{
//取消关键字,避免出现 nulllll多个l
lastKeywordChar = ' ';
}
break;
case 's'://false
isError = lastChar != 'l';
break;
case '.'://数字可以出现小数点,但不能重复出现
isError = keyValueState != 1 || lastKeywordChar == '.';
break;
case ' ':
if (lastChar == '.') { isError = true; }
else if (jsonStart && !arrayStart)
{
valueStart = -2;//遇到空格,结束取值。
}
break;
default:
//不是引号开头的,只允许数字[1]
isError = c < 48 || c > 57;
break;
}
}
//值开头的,只能是:["xxx"] {[{}]
}
break;
}
if (isError)
{
//
}
}
/// <summary>
/// 设置字符状态(返回true则为关键词返回false则当为普通字符处理
/// </summary>
internal bool IsKeyword(char c)
{
bool isKeyword = false;
switch (c)
{
case '{'://[{ "[{A}]":[{"[{B}]":3,"m":"C"}]}]
#region
if (keyStart <= 0 && valueStart <= 0)
{
if (jsonStart && keyValueState == 1)
{
valueStart = 0;
childrenStart = true;
}
else
{
keyValueState = 0;
}
jsonStart = true;//开始。
isKeyword = true;
}
#endregion
break;
case '}':
#region
if (lastChar != '.')
{
if (keyStart <= 0 && valueStart < 2)
{
if (jsonStart)
{
jsonStart = false;//正常结束。
valueStart = -1;
keyValueState = 0;
setDicValue = true;
}
isKeyword = true;
}
}
#endregion
break;
case '[':
#region
if (!jsonStart)
{
arrayStart = true;
isKeyword = true;
}
else if (jsonStart && keyValueState == 1 && valueStart < 2)
{
childrenStart = true;
isKeyword = true;
}
#endregion
break;
case ']':
#region
if (lastChar != '.')
{
if (!jsonStart && (keyStart <= 0 && valueStart <= 0) || (keyStart == -1 && valueStart == 1))
{
if (arrayStart)// && !childrenStart
{
arrayStart = false;
}
isKeyword = true;
}
}
#endregion
break;
case '"':
case '\'':
// CheckIsError(c);
if (isStrictMode && c == '\'')
{
break;
}
#region
if (jsonStart || arrayStart)
{
if (!jsonStart && arrayStart)
{
keyValueState = 1;//如果是数组只有取值没有Key所以直接跳过0
}
if (keyValueState == 0)//key阶段
{
keyStart = (keyStart <= 0 ? (c == '"' ? 3 : 2) : -2);
isKeyword = true;
}
else if (keyValueState == 1)//值阶段
{
if (valueStart <= 0)
{
valueStart = (c == '"' ? 3 : 2);
isKeyword = true;
}
else if ((valueStart == 2 && c == '\'') || (valueStart == 3 && c == '"'))
{
if (!escapeChar)
{
valueStart = -2;
isKeyword = true;
}
else
{
escapeChar = false;
}
}
}
}
#endregion
break;
case ':':
// CheckIsError(c);
#region
if (jsonStart && keyStart < 2 && valueStart < 2 && keyValueState == 0)
{
keyStart = -2;//0 结束key
keyValueState = 1;
isKeyword = true;
}
#endregion
break;
case ',':
#region {"a": [11,"22", ], "Type": 2.}
if (lastChar != '.')
{
if (jsonStart && keyStart < 2 && valueStart < 2 && keyValueState == 1)
{
keyValueState = 0;
valueStart = 0;
setDicValue = true;
isKeyword = true;
}
else if (arrayStart && !jsonStart) //[a,b] [",",33] [{},{}]
{
if ((keyValueState == -1 && valueStart == -1) || (valueStart < 2 && keyValueState == 1))
{
valueStart = 0;
isKeyword = true;
}
}
}
#endregion
break;
case ' ':
case '\r':
case '\n':
case '\t':
if (jsonStart && keyStart <= 1 && valueStart <= 1)
{
isKeyword = true;
// return true;//跳过空格。
}
break;
case 't'://true
case 'f'://false
case 'n'://null
case '-'://-388.8 //负的数字符号
if (lastKeywordChar != c && lastKeywordChar != '.')
{
if (valueStart <= 1 && ((arrayStart && !jsonStart && keyStart == -1) || (jsonStart && keyValueState == 1 && valueStart <= 0)))
{
//只改状态,不是关键字
valueStart = 1;
lastChar = c;
lastKeywordChar = c;
return false;//直接返回,不检测错误。
}
}
break;
case '.':
if ((jsonStart || arrayStart) && keyValueState == 1 && valueStart == 1 && lastKeywordChar != c)
{
lastChar = c;
lastKeywordChar = c;//记录符号,数字只能有一个符号。
return false;//不检测错误。
}
break;
default: //值开头。。
// CheckIsError(c);
if (c == '\\') //转义符号
{
if (escapeChar)
{
escapeChar = false;
}
else
{
escapeChar = true;
}
}
if (jsonStart)
{
if (keyStart <= 0 && keyValueState <= 0)
{
keyStart = 1;//无引号的
}
else if (valueStart <= 0 && keyValueState == 1)
{
valueStart = 1;//无引号的
}
}
else if (arrayStart)
{
keyValueState = 1;
if (valueStart < 1)
{
valueStart = 1;//无引号的
}
}
break;
}
if (escapeChar && c != '\\')
{
escapeChar = false;
}
if (!isKeyword)
{
CheckIsError(c);
}
else
{
lastKeywordChar = c;
}
lastChar = c;
return isKeyword;
}
}
}