首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Lemon (和)进行JSON解析

使用Lemon (和)进行JSON解析
EN

Stack Overflow用户
提问于 2014-10-28 18:24:20
回答 1查看 318关注 0票数 2

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

以下是目前为止的代码:

代码语言:javascript
复制
%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

代码语言:javascript
复制
{ \"hello\" : \"world\" }

我无法通过members规则(此时,字典已被正确设置)。

对象规则永远不会被调用,json ::=对象也会这样做!

我在做什么蠢事吗?

如有任何意见,将不胜感激!

EN

回答 1

Stack Overflow用户

发布于 2015-12-09 17:48:02

你得打电话给帕瑟(.)值为零的函数,用于运行令牌流时的第二个参数。

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

代码语言:javascript
复制
   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行,它对解析器说,它不应该期望更多的令牌,并且可以执行保留的规则。

基本上,程序要使用柠檬生成的解析器必须做的是首先创建解析器,然后通过标记输入源来发送大量令牌。当到达输入结束时,应该最后一次调用Parse()例程,标记类型为0。这一步骤是必要的,以通知解析器输入的结束已经到达。最后,我们通过调用ParseFree()来回收解析器使用的内存。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26615726

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档