gpt4 book ai didi

ios - 使用Lemon(和Core Foundation)进行JSON解析

转载 作者:行者123 更新时间:2023-12-01 16:37:49 25 4
gpt4 key购买 nike

我正在尝试使用Lemon和Apple Core Foundation编写一个简单的JSON解析器。

这是到目前为止的代码:

%include {

#import <CoreFoundation/CoreFoundation.h>

#import "state.h" // struct ParserState { CFTypeRef result; };
#import "tuple.h" // struct Tuple { CFTypeRef one; CFTypeRef two; };

}

%start_symbol json

%token_type { CFTypeRef }
%token_prefix T

%extra_argument { ParserStateRef state }

%type simple_value { CFTypeRef }
%type member { TupleRef }
%type members { CFMutableDictionaryRef }
%type object { CFMutableDictionaryRef }
%type array { CFMutableArrayRef }

simple_value(A) ::= STRING(B). { A = B; }
simple_value(A) ::= INT(B). { A = B; }
simple_value(A) ::= FLOAT(B). { A = B; }
simple_value(A) ::= FALSE. { A = kCFBooleanFalse; }
simple_value(A) ::= TRUE. { A = kCFBooleanTrue; }
simple_value(A) ::= NULL. { A = kCFNull; }

member(A) ::= STRING(B) COLON simple_value(C). {
A = TupleCreate(B,C);
}
member ::= STRING COLON object.
member ::= STRING COLON array.

members(A) ::= member(B). {
A = CFDictionaryCreateMutable(kCFAllocatorDefault,0,&kCFTypeDictionaryKeyCallBacks,&kCFTypeDictionaryValueCallBacks);
CFDictionarySetValue(A, B->first, B->second);
CFRelease(B->first);
CFRelease(B->second);
TupleRelease(B);
}
members(A) ::= members(B) COMMA member(C). {
CFDictionarySetValue(B, C->first, C->second);
CFRelease(C->first);
CFRelease(C->second);
TupleRelease(C);
A = B;
}

values ::= value.
values ::= values COMMA value.

object(A) ::= LCB RCB. {
/* THIS NEVER GETS CALLED */
A = CFDictionaryCreateMutable(kCFAllocatorDefault,0,&kCFTypeDictionaryKeyCallBacks,&kCFTypeDictionaryValueCallBacks);
}
object(A) ::= LCB members(B) RCB. {
/* THIS NEVER GETS CALLED */
A = B;
}

array ::= LSB RSB.
array ::= LSB values RSB.

value ::= array.
value ::= object.
value ::= simple_value.

json ::= object(A). { state->result = A; }
json ::= array.

用这样的简单JSON
{ \"hello\" : \"world\" }

我无法超越 成员规则(此时,字典已正确设置)。

永远不会调用 对象规则,而 json::=对象会执行相同的操作!

我在做蠢事吗?

任何输入将不胜感激!

最佳答案

当 token 流用完时,必须为第二个参数使用零值调用Parser(...)函数。

信息来自:https://www.sqlite.org/src/doc/trunk/doc/lemon.html

   01 ParseTree *ParseFile(const char *zFilename){
02 Tokenizer *pTokenizer;
03 void *pParser;
04 Token sToken;
05 int hTokenId;
06 ParserState sState;
07
08 pTokenizer = TokenizerCreate(zFilename);
09 pParser = ParseAlloc( malloc );
10 InitParserState(&sState);
11 while( GetNextToken(pTokenizer, &hTokenId, &sToken) ){
12 Parse(pParser, hTokenId, sToken, &sState);
13 }
14 Parse(pParser, 0, sToken, &sState);
15 ParseFree(pParser, free );
16 TokenizerFree(pTokenizer);
17 return sState.treeRoot;
18 }

参见第14行。它向解析器表示,它不应期望更多的 token ,并且可以执行其余规则。

基本上,程序使用Lemon生成的解析器所要做的是首先创建解析器,然后向其发送通过标记输入源获得的许多标记。当到达输入的结尾时,应该使用 token 类型0再次调用Parse()例程。此步骤对于通知解析器已到达输入的结尾是必需的。最后,我们通过调用ParseFree()回收解析器使用的内存。

关于ios - 使用Lemon(和Core Foundation)进行JSON解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26615726/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com