/* JSON_checker.h */

typedef struct JSON_checker_struct {
int valid;
int state;
int depth;
int top;
int* stack;
} * JSON_checker; extern JSON_checker new_JSON_checker(int depth);
extern int JSON_checker_char(JSON_checker jc, int next_char);
extern int JSON_checker_done(JSON_checker jc);
/* JSON_checker.c */

/* 2016-11-11 */

/*
Copyright (c) 2005 JSON.org Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. The Software shall be used for Good, not Evil. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/ #include <stdlib.h>
#include "JSON_checker.h" #define TRUE 1
#define FALSE 0
#define GOOD 0xBABAB00E
#define __ -1 /* the universal error code */ /*
Characters are mapped into these 31 character classes. This allows for
a significant reduction in the size of the state transition table.
*/ enum classes {
C_SPACE, /* space */
C_WHITE, /* other whitespace */
C_LCURB, /* { */
C_RCURB, /* } */
C_LSQRB, /* [ */
C_RSQRB, /* ] */
C_COLON, /* : */
C_COMMA, /* , */
C_QUOTE, /* " */
C_BACKS, /* \ */
C_SLASH, /* / */
C_PLUS, /* + */
C_MINUS, /* - */
C_POINT, /* . */
C_ZERO , /* 0 */
C_DIGIT, /* 123456789 */
C_LOW_A, /* a */
C_LOW_B, /* b */
C_LOW_C, /* c */
C_LOW_D, /* d */
C_LOW_E, /* e */
C_LOW_F, /* f */
C_LOW_L, /* l */
C_LOW_N, /* n */
C_LOW_R, /* r */
C_LOW_S, /* s */
C_LOW_T, /* t */
C_LOW_U, /* u */
C_ABCDF, /* ABCDF */
C_E, /* E */
C_ETC, /* everything else */
NR_CLASSES
}; static int ascii_class[] = {
/*
This array maps the 128 ASCII characters into character classes.
The remaining Unicode characters should be mapped to C_ETC.
Non-whitespace control characters are errors.
*/
__, __, __, __, __, __, __, __,
__, C_WHITE, C_WHITE, __, __, C_WHITE, __, __,
__, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __, C_SPACE, C_ETC, C_QUOTE, C_ETC, C_ETC, C_ETC, C_ETC, C_ETC,
C_ETC, C_ETC, C_ETC, C_PLUS, C_COMMA, C_MINUS, C_POINT, C_SLASH,
C_ZERO, C_DIGIT, C_DIGIT, C_DIGIT, C_DIGIT, C_DIGIT, C_DIGIT, C_DIGIT,
C_DIGIT, C_DIGIT, C_COLON, C_ETC, C_ETC, C_ETC, C_ETC, C_ETC, C_ETC, C_ABCDF, C_ABCDF, C_ABCDF, C_ABCDF, C_E, C_ABCDF, C_ETC,
C_ETC, C_ETC, C_ETC, C_ETC, C_ETC, C_ETC, C_ETC, C_ETC,
C_ETC, C_ETC, C_ETC, C_ETC, C_ETC, C_ETC, C_ETC, C_ETC,
C_ETC, C_ETC, C_ETC, C_LSQRB, C_BACKS, C_RSQRB, C_ETC, C_ETC, C_ETC, C_LOW_A, C_LOW_B, C_LOW_C, C_LOW_D, C_LOW_E, C_LOW_F, C_ETC,
C_ETC, C_ETC, C_ETC, C_ETC, C_LOW_L, C_ETC, C_LOW_N, C_ETC,
C_ETC, C_ETC, C_LOW_R, C_LOW_S, C_LOW_T, C_LOW_U, C_ETC, C_ETC,
C_ETC, C_ETC, C_ETC, C_LCURB, C_ETC, C_RCURB, C_ETC, C_ETC
}; /*
The state codes.
*/
enum states {
GO, /* start */
OK, /* ok */
OB, /* object */
KE, /* key */
CO, /* colon */
VA, /* value */
AR, /* array */
ST, /* string */
ES, /* escape */
U1, /* u1 */
U2, /* u2 */
U3, /* u3 */
U4, /* u4 */
MI, /* minus */
ZE, /* zero */
IN, /* integer */
FR, /* fraction */
FS, /* fraction */
E1, /* e */
E2, /* ex */
E3, /* exp */
T1, /* tr */
T2, /* tru */
T3, /* true */
F1, /* fa */
F2, /* fal */
F3, /* fals */
F4, /* false */
N1, /* nu */
N2, /* nul */
N3, /* null */
NR_STATES
}; static int state_transition_table[NR_STATES][NR_CLASSES] = {
/*
The state transition table takes the current state and the current symbol,
and returns either a new state or an action. An action is represented as a
negative number. A JSON text is accepted if at the end of the text the
state is OK and if the mode is MODE_DONE. white 1-9 ABCDF etc
space | { } [ ] : , " \ / + - . 0 | a b c d e f l n r s t u | E |*/
/*start GO*/ {GO,GO,-,__,-,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
/*ok OK*/ {OK,OK,__,-,__,-,__,-,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
/*object OB*/ {OB,OB,__,-,__,__,__,__,ST,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
/*key KE*/ {KE,KE,__,__,__,__,__,__,ST,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
/*colon CO*/ {CO,CO,__,__,__,__,-,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
/*value VA*/ {VA,VA,-,__,-,__,__,__,ST,__,__,__,MI,__,ZE,IN,__,__,__,__,__,F1,__,N1,__,__,T1,__,__,__,__},
/*array AR*/ {AR,AR,-,__,-,-,__,__,ST,__,__,__,MI,__,ZE,IN,__,__,__,__,__,F1,__,N1,__,__,T1,__,__,__,__},
/*string ST*/ {ST,__,ST,ST,ST,ST,ST,ST,-,ES,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST},
/*escape ES*/ {__,__,__,__,__,__,__,__,ST,ST,ST,__,__,__,__,__,__,ST,__,__,__,ST,__,ST,ST,__,ST,U1,__,__,__},
/*u1 U1*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,U2,U2,U2,U2,U2,U2,U2,U2,__,__,__,__,__,__,U2,U2,__},
/*u2 U2*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,U3,U3,U3,U3,U3,U3,U3,U3,__,__,__,__,__,__,U3,U3,__},
/*u3 U3*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,U4,U4,U4,U4,U4,U4,U4,U4,__,__,__,__,__,__,U4,U4,__},
/*u4 U4*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,ST,ST,ST,ST,ST,ST,ST,ST,__,__,__,__,__,__,ST,ST,__},
/*minus MI*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,ZE,IN,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
/*zero ZE*/ {OK,OK,__,-,__,-,__,-,__,__,__,__,__,FR,__,__,__,__,__,__,E1,__,__,__,__,__,__,__,__,E1,__},
/*int IN*/ {OK,OK,__,-,__,-,__,-,__,__,__,__,__,FR,IN,IN,__,__,__,__,E1,__,__,__,__,__,__,__,__,E1,__},
/*frac FR*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,FS,FS,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
/*fracs FS*/ {OK,OK,__,-,__,-,__,-,__,__,__,__,__,__,FS,FS,__,__,__,__,E1,__,__,__,__,__,__,__,__,E1,__},
/*e E1*/ {__,__,__,__,__,__,__,__,__,__,__,E2,E2,__,E3,E3,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
/*ex E2*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,E3,E3,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
/*exp E3*/ {OK,OK,__,-,__,-,__,-,__,__,__,__,__,__,E3,E3,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
/*tr T1*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,T2,__,__,__,__,__,__},
/*tru T2*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,T3,__,__,__},
/*true T3*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,OK,__,__,__,__,__,__,__,__,__,__},
/*fa F1*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,F2,__,__,__,__,__,__,__,__,__,__,__,__,__,__},
/*fal F2*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,F3,__,__,__,__,__,__,__,__},
/*fals F3*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,F4,__,__,__,__,__},
/*false F4*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,OK,__,__,__,__,__,__,__,__,__,__},
/*nu N1*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,N2,__,__,__},
/*nul N2*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,N3,__,__,__,__,__,__,__,__},
/*null N3*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,OK,__,__,__,__,__,__,__,__}
}; /*
These modes can be pushed on the stack.
*/
enum modes {
MODE_ARRAY,
MODE_DONE,
MODE_KEY,
MODE_OBJECT
}; static void
destroy(JSON_checker jc)
{
/*
Delete the JSON_checker object.
*/
jc->valid = ;
free((void*)jc->stack);
free((void*)jc);
} static int
reject(JSON_checker jc)
{
/*
Delete the JSON_checker object.
*/
destroy(jc);
return FALSE;
} static int
push(JSON_checker jc, int mode)
{
/*
Push a mode onto the stack. Return false if there is overflow.
*/
jc->top += ;
if (jc->top >= jc->depth) {
return FALSE;
}
jc->stack[jc->top] = mode;
return TRUE;
} static int
pop(JSON_checker jc, int mode)
{
/*
Pop the stack, assuring that the current mode matches the expectation.
Return false if there is underflow or if the modes mismatch.
*/
if (jc->top < || jc->stack[jc->top] != mode) {
return FALSE;
}
jc->top -= ;
return TRUE;
} JSON_checker
new_JSON_checker(int depth)
{
/*
new_JSON_checker starts the checking process by constructing a JSON_checker
object. It takes a depth parameter that restricts the level of maximum
nesting. To continue the process, call JSON_checker_char for each character in the
JSON text, and then call JSON_checker_done to obtain the final result.
These functions are fully reentrant. The JSON_checker object will be deleted by JSON_checker_done.
JSON_checker_char will delete the JSON_checker object if it sees an error.
*/
JSON_checker jc = (JSON_checker)malloc(sizeof(struct JSON_checker_struct));
jc->valid = GOOD;
jc->state = GO;
jc->depth = depth;
jc->top = -;
jc->stack = (int*)calloc(depth, sizeof(int));
push(jc, MODE_DONE);
return jc;
} int
JSON_checker_char(JSON_checker jc, int next_char)
{
/*
After calling new_JSON_checker, call this function for each character (or
partial character) in your JSON text. It can accept UTF-8, UTF-16, or
UTF-32. It returns TRUE if things are looking ok so far. If it rejects the
text, it deletes the JSON_checker object and returns false.
*/
int next_class, next_state;
/*
Determine the character's class.
*/
if (jc->valid != GOOD) {
return FALSE;
}
if (next_char < ) {
return reject(jc);
}
if (next_char >= ) {
next_class = C_ETC;
} else {
next_class = ascii_class[next_char];
if (next_class <= __) {
return reject(jc);
}
}
/*
Get the next state from the state transition table.
*/
next_state = state_transition_table[jc->state][next_class];
if (next_state >= ) {
/*
Change the state.
*/
jc->state = next_state;
/*
Or perform one of the actions.
*/
} else {
switch (next_state) {
/* empty } */
case -:
if (!pop(jc, MODE_KEY)) {
return reject(jc);
}
jc->state = OK;
break; /* } */ case -:
if (!pop(jc, MODE_OBJECT)) {
return reject(jc);
}
jc->state = OK;
break; /* ] */ case -:
if (!pop(jc, MODE_ARRAY)) {
return reject(jc);
}
jc->state = OK;
break; /* { */ case -:
if (!push(jc, MODE_KEY)) {
return reject(jc);
}
jc->state = OB;
break; /* [ */ case -:
if (!push(jc, MODE_ARRAY)) {
return reject(jc);
}
jc->state = AR;
break; /* " */ case -:
switch (jc->stack[jc->top]) {
case MODE_KEY:
jc->state = CO;
break;
case MODE_ARRAY:
case MODE_OBJECT:
jc->state = OK;
break;
default:
return reject(jc);
}
break; /* , */ case -:
switch (jc->stack[jc->top]) {
case MODE_OBJECT:
/*
A comma causes a flip from object mode to key mode.
*/
if (!pop(jc, MODE_OBJECT) || !push(jc, MODE_KEY)) {
return reject(jc);
}
jc->state = KE;
break;
case MODE_ARRAY:
jc->state = VA;
break;
default:
return reject(jc);
}
break; /* : */ case -:
/*
A colon causes a flip from key mode to object mode.
*/
if (!pop(jc, MODE_KEY) || !push(jc, MODE_OBJECT)) {
return reject(jc);
}
jc->state = VA;
break;
/*
Bad action.
*/
default:
return reject(jc);
}
}
return TRUE;
} int
JSON_checker_done(JSON_checker jc)
{
/*
The JSON_checker_done function should be called after all of the characters
have been processed, but only if every call to JSON_checker_char returned
TRUE. This function deletes the JSON_checker and returns TRUE if the JSON
text was accepted.
*/
if (jc->valid != GOOD) {
return FALSE;
}
int result = jc->state == OK && pop(jc, MODE_DONE);
destroy(jc);
return result;
}
/* main.c */

/*
This program demonstrates a simple application of JSON_checker. It reads
a JSON text from STDIN, producing an error message if the text is rejected. % JSON_checker <test/pass1.json
*/ #include <stdlib.h>
#include <stdio.h>
#include "JSON_checker.h" int main(int argc, char* argv[]) {
/*
Read STDIN. Exit with a message if the input is not well-formed JSON text. jc will contain a JSON_checker with a maximum depth of 20.
*/
JSON_checker jc = new_JSON_checker();
for (;;) {
int next_char = getchar();
if (next_char <= ) {
break;
}
if (!JSON_checker_char(jc, next_char)) {
fprintf(stderr, "JSON_checker_char: syntax error\n");
exit();
}
}
if (!JSON_checker_done(jc)) {
fprintf(stderr, "JSON_checker_end: syntax error\n");
exit();
}
}

JSONCkecker(C语言版本)的更多相关文章

  1. MFCC特征提取(C语言版本)

    音频分析中,MFCC参数是经典参数之一.之前对于它的计算流程和原理,大体上是比较清楚的,所以仿真的时候,都是直接调用matlab的voicebox工具或者开发的时候直接调用第三方库.最近想整理一个纯C ...

  2. android 多语言版本开发

    最近项目中用用到语言切换功能,第一想到的就是资源文件,没错. 在资源文件中新建一个文件夹values-en,en表示英语,有一些还细化到地区,如values-en-rUS 即美国地区的英语,r是必需的 ...

  3. zookeeper 学习笔记 (C语言版本)

    1.zookeeper简介 zookeeper是Hadoop的子项目,在大型分布式系统中,zookeeper封装好了一些复杂易出错的服务,提供简单易用的接口,给使用者提供高效稳定的服务.这些服务包括配 ...

  4. T-SQL: 17 个与日期时间相关的自定义函数(UDF),周日作为周的最后一天,均不受 @@DateFirst、语言版本影响!

    原文:T-SQL: 17 个与日期时间相关的自定义函数(UDF),周日作为周的最后一天,均不受 @@DateFirst.语言版本影响! CSDN 的 Blog 太滥了!无时不刻地在坏! 开始抢救性搬家 ...

  5. 阿里云ECS服务器云监控(cloudmonitor)Go语言版本插件安装卸载与维护

    云监控Go语言版本插件安装_主机监控_用户指南_云监控-阿里云https://help.aliyun.com/document_detail/97929.html 云监控cloudmonitor 1. ...

  6. WinForm多语言版本实战项目演练

    一.课程介绍 关于如何实现“WinForm多语言版本”网上有很多实现技术方案,可以说是“琳琅满目”,"包罗万象".俗话说的好:一千个读者就有一千个哈姆雷特!如果您工作中恰好也遇到这 ...

  7. ios-多语言版本开发(三)(转载)

    写在前面  iOS 多语言版本的开发(二)中我们实现了如何让用户自己去切换系统语言的功能,我们还写了Demo 以供辅助学习:但是,继以上两篇文章都是建立在项目刚刚启动或启动不久,项目中存在的中文字符串 ...

  8. iOS-多语言版本开发(二)(转载)

    题记   iOS 多语言版本的开发(一) 中我们完成了让应用跟随系统语言进行切换,而用户自己却不能切换的功能,也基本上算是实现了多语言版本:可是,对于某些应用来说,实现跟随系统语言切换的同时, 也想要 ...

  9. iOS-多语言版本的开发(一)(转载)

    引言  多语言 & 本地化,随你怎么叫,道理差不多:一个App 要想走出国门,只支持一种语言是不能够的,也是不可能的,多元化世界已经融入我们的生活,对于一些应用,开发多语言版本,已经是不可避免 ...

  10. 再编写代码中报错:CS8107 C# 7.0 中不支持功能“xxxxxx”。请使用 7.1 或更高的语言版本。

    解决方法:项目右键属性 ---> 生成 ---> 找到最下面的高级按钮,点击高级按钮 ---> 常规 ---> 语言版本 ---> 选择 C#最新次要版本,或者比当前版本 ...

随机推荐

  1. Linux学习笔记之Django项目部署(CentOS)

    一.引入 用Django写了一个测试的项目,现在要部署在Linux上,一般这种情况下,只要在项目里面敲一行命令:python manage.py runserver 0.0.0.0:8000就行了.但 ...

  2. vue IE 报错 引用babel-polyfill

    一.vue 项目报错 vuex requires a Promise polyfill in this browser     在网上找到下面三篇文章,然而和我的项目都不太一样. 我的项目基于 基础模 ...

  3. 易宝支付Demo,生产中封装成简洁的代付接口,不用request如何获取项目运行时的真实路径

    最近项目在做融360引流,涉及到了易宝支付的代扣和代付.易宝官方给出的demo只能简单运行,而且都是通过form表单的形式提交,返回XML格式.同时接口代码都写在了JSP中看起来不友好.项目在生成中想 ...

  4. hash 和pushState,replaceState

    hash 要点: 1.不会向后台发请求:#是用来指导浏览器动作的,对服务器端完全无用. 2.用来跳转到页面的指定位置:   为网页位置指定标识符,有两个方法.一是使用锚点,比如<a name=& ...

  5. JS预解析机制

    JS的预解析过程: 1,预解析 2,再逐行解读代码, 实例: ---------------------------- <script>        var name="xm& ...

  6. 4 ;XHTML表格

    1.表格的基本格式 2.<table>标签下的常用属性 3.<table>标签下的边框设置 4.<tr><th><td>标签下的常用属性 5 ...

  7. angular select 默认值

    <select ng-model="selected" ng-options="x.id as x.name for x in users">< ...

  8. K8S RBAC

    API Server 内部通过用户认证后,然后进入授权流程.对合法用户进行授权并且随后在用户访问时进行鉴权,是权限管理的重要环节. 在 kubernetes 集群中,各种操作权限是赋予角色(Role ...

  9. [JavaScript]手机滑动图片

    思路 1.用ul ,li 来装载滑动的图片,超出部分隐藏 2.滑动是通过改变ul的位置来实现 布局 模块 1: 根据li元素个数去设置ul的宽度 1.1 获取ul元素 1.2 获取li元素的个数 1. ...

  10. JS中的柯里化(currying)

    何为Curry化/柯里化? curry化来源与数学家 Haskell Curry的名字 (编程语言 Haskell也是以他的名字命名). 柯里化通常也称部分求值,其含义是给函数分步传递参数,每次传递参 ...