在使用Xcode和YACC时遇到"Unknown type name"错误

18
我是一名有用的助手,可以将文本翻译成中文。
我正在尝试在原生支持YACC的xcode中使用它。为此,我找到了一个漂亮的this示例。我的想法是构建自己的语法,因此我开始尝试该项目,看看是否支持我所需的内容。因此,我创建了以下接口:

.h

#import <Foundation/Foundation.h>

@interface HYPLangNodeNP : NSObject

@end

.m

#import "HYPLangNodeNP.h"

@implementation HYPLangNodeNP

@end

是的,它只是一个空实现。然后我对语法做了两个更改:

1)添加HYPLangNodeNP导入

%{

#import "MessageBlocks.h"
#import "HYPLangNodeNP.h"

int yylex(void);
void yyerror(char *s);

%}

2) 将HYPLangNodeNP添加到类型%union中

%union {
    float     value;
    NSString *identifier;
    HYPLangNodeNP *node;
}

该项目编译失败,出现Unknown type name 'HYPLangNodeNP'。有人知道如何解决吗?
编辑:
我不知道YACC版本,但它是随Xcode 6.3一起提供的任何版本。以下是我得到的日志:
CompileC /Users/RafaelSoares/Library/Developer/Xcode/DerivedData/Parser_Test-ahryrrrgjyqtbhenhxphagqdgppf/Build/Intermediates/Parser Test.build/Debug-iphonesimulator/Parser Test.build/Objects-normal/i386/ViewController.o Parser Test/ViewController.m normal i386 objective-c com.apple.compilers.llvm.clang.1_0.compiler cd "/Users/RafaelSoares/Google Drive/Hype/ParserTest-master " export LANG=en_US.US-ASCII export PATH="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin:/Applications/Xcode.app/Contents/Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin" /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -x objective-c -arch i386 -fmessage-length=0 -fdiagnostics-show-note-include-stack -fmacro-backtrace-limit=0 -std=gnu99 -Wno-trigraphs -fpascal-strings -O0 -Wno-missing-field-initializers -Wno-missing-prototypes -Wno-implicit-atomic-properties -Wno-receiver-is-weak -Wno-arc-repeated-use-of-weak -Wno-missing-braces -Wparentheses -Wswitch -Wno-unused-function -Wno-unused-label -Wno-unused-parameter -Wunused-variable -Wunused-value -Wno-empty-body -Wuninitialized -Wno-unknown-pragmas -Wno-shadow -Wno-four-char-constants -Wno-conversion -Wno-constant-conversion -Wno-int-conversion -Wno-bool-conversion -Wno-enum-conversion -Wno-shorten-64-to-32 -Wpointer-sign -Wno-newline-eof -Wno-selector -Wno-strict-selector-match -Wno-undeclared-selector -Wno-deprecated-implementations -DDEBUG=1 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator8.3.sdk -fexceptions -fasm-blocks -fstrict-aliasing -Wprotocol -Wdeprecated-declarations -g -Wno-sign-conversion -fobjc-abi-version=2 -fobjc-legacy-dispatch -mios-simulator-version-min=8.3 -iquote /Users/RafaelSoares/Library/Developer/Xcode/DerivedData/Parser_Test-ahryrrrgjyqtbhenhxphagqdgppf/Build/Intermediates/Parser Test.build/Debug-iphonesimulator/Parser Test.build/Parser Test-generated-files.hmap -I/Users/RafaelSoares/Library/Developer/Xcode/DerivedData/Parser_Test-ahryrrrgjyqtbhenhxphagqdgppf/Build/Intermediates/Parser Test.build/Debug-iphonesimulator/Parser Test.build/Parser Test-own-target-headers.hmap -I/Users/RafaelSoares/Library/Developer/Xcode/DerivedData/Parser_Test-ahryrrrgjyqtbhenhxphagqdgppf/Build/Intermediates/Parser Test.build/Debug-iphonesimulator/Parser Test.build/Parser Test-all-target-headers.hmap -iquote /Users/RafaelSoares/Library/Developer/Xcode/DerivedData/Parser_Test-ahryrrrgjyqtbhenhxphagqdgppf/Build/Intermediates/Parser Test.build/Debug-iphonesimulator/Parser Test.build/Parser Test-project-headers.hmap -I/Users/RafaelSoares/Library/Developer/Xcode/DerivedData/Parser_Test-ahryrrrgjyqtbhenhxphagqdgppf/Build/Products/Debug-iphonesimulator/include -I/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include -I/Users/RafaelSoares/Library/Developer/Xcode/DerivedData/Parser_Test-ahryrrrgjyqtbhenhxphagqdgppf/Build/Intermediates/Parser Test.build/Debug-iphonesimulator/Parser Test.build/DerivedSources/i386 -I/Users/RafaelSoares/Library/Developer/Xcode/DerivedData/Parser_Test-ahryrrrgjyqtbhenhxphagqdgppf/Build/Intermediates/Parser Test.build/Debug-iphonesimulator/Parser Test.build/DerivedSources -F/Users/RafaelSoares/Library/Developer/Xcode/DerivedData/Parser_Test-ahryrrrgjyqtbhen

你需要展示完整的命令行和错误日志,这样我们才能看到发生了什么。在Xcode中:按Command-8,找到失败的命令,然后将鼠标悬停在上面并点击汉堡图标以查看完整详情(是的,很简单,对吧?) - Ewan Mellor
我的猜测是 "%code requires" 会有所帮助:http://www.gnu.org/software/bison/manual/html_node/_0025code-Summary.html#g_t_0025code-Summary "...换句话说,这是定义在 %union 指令中引用的类型的最佳位置。" - Ewan Mellor
此外,您应该说明您正在使用哪个yacc / bison实现和版本。 - Ewan Mellor
@EwanMellor,请查看我的编辑。 - Rafael Soares
1个回答

19

我已经查看了这个问题并有一些答案,但不幸的是,在现有时间内没有一个完整的工作示例。我对lex和yacc非常熟悉,但以前没有用过Objective-C。很抱歉,这是我第一个Objective-C练习,我在那方面的弱点让我失望了。也许您在那个领域的更好知识将使您能够完成任务。

正如@Ewan Mellor所提示的那样,问题的第一部分在bison手册*中有解释,其中指出yacc针对某些语言/编译器生成代码的顺序不正确。对于Objective-C来说是正确的,这就是导致您收到编译错误的原因。具体来说,这意味着yacc的%union结构难以与Objective-C对象一起使用(正如您发现的那样)。

还有另一种解决这个问题的方法,如这篇文章所示。

其中一种方法是使用YYSTYPE宏来替换yacc使用的类型,而不是%union

我进行了以下更改以使用此方法:

在MessageBlocks.h中:

@interface HYPLangNodeNP : NSObject
@end
@interface YYresultType : NSObject

- (float) value;
- (NSString *) identifier;
- (HYPLangNodeNP *)node;
- (void) setvalue: (float)input;
- (void) setidentifier: (NSString *)input;
- (void) setnode: (HYPLangNodeNP *)input;

@end

在MessageBlocks.m文件中:

@implementation HYPLangNodeNP : NSObject

int dummy;

@end

@implementation YYresultType : NSObject
float     value;
NSString *identifier;
HYPLangNodeNP *node;

- (float) value {
    return value;
}

- (NSString *) identifier {
    return identifier;
}

- (HYPLangNodeNP *) node {
    return node;
}

- (void) setvalue: (float)input {
    value = input;
}

- (void) setidentifier: (NSString *)input {
    identifier = input;
}

- (void) setnode: (HYPLangNodeNP *)input {
    node = input;
}
在tokenizer.lm中:
[0-9]+\.[0-9]* { [yylval setvalue: [float atof(yytext)]]; return FLOAT; }

[0-9]+ { [yylval setvalue: [float atof(yytext)]]; return INTEGER; }

[a-zA-Z]+ { [yylval setidentifier : [ [NSString stringWithFormat:@"%s", yytext] retain]; return IDENTIFIER; }

在 Parser.ym 文件中:

%{

#import "MessageBlocks.h"

int yylex(void);
void yyerror(char *s);
#define YYSTYPE YYresultType
%}

/*
%union {
    float     value;
    NSString *identifier;
    HYPLangNodeNP *node;
}*/

...

and so on.

我仍然在遇到Objective-C编译错误,所以我和你一样没有取得进展,但我会继续努力……但可能对你没什么用。


* 请参见本节的最后一段

本节说明了四种Prologue替代方案相对于原始Yacc Prologue的优势。

它解释了yacc代码排序的弱点以及bison如何通过%code指令克服这个问题。 Xcode内置的是yacc而不是bison,但可以将系统上的yacc替换为bison以克服这个缺陷。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接