antlr / grammars-v4

Grammars written for ANTLR v4; expectation that the grammars are free of actions.
MIT License
10.08k stars 3.68k forks source link

API_AVAILABLE macro causes parsing errors in objc grammar #2030

Open justin-iteratively opened 3 years ago

justin-iteratively commented 3 years ago

Problem

References to API_AVAILABLE() cause parse errors using objc grammar.

Example Source

// myFile.m
@interface aInterface ()
@property(nonatomic, readwrite) double aProperty API_AVAILABLE(ios(14), macosx(10.13));
@end

- (void)myMethod:(MYObject *)arg API_AVAILABLE(ios(14)) {
}

Error output

line 34:70 extraneous input '(' expecting {'BOOL', 'Class', 'bycopy', 'byref', 'id', 'IMP', 'in', 'inout', 'oneway', 'out', 'Protocol', 'SEL', 'self', 'super', 'atomic', 'nonatomic', 'retain', '__autoreleasing', '__block', '__bridge_retained', '__bridge_transfer', '__covariant', '__contravariant', '__deprecated', '__kindof', '__unused', NULL_UNSPECIFIED, NULLABLE, NONNULL, 'null_resettable', 'NS_INLINE', 'NS_ENUM', 'NS_OPTIONS', 'assign', 'copy', 'getter', 'setter', 'strong', 'readonly', 'readwrite', 'weak', 'unsafe_unretained', 'IBOutlet', 'IBOutletCollection', 'IBInspectable', 'IB_DESIGNABLE', IDENTIFIER, ';'}

line 34:78 extraneous input ')' expecting ';'

line 503:88 mismatched input '(' expecting {'{', ';'}

line 530:6 extraneous input '[' expecting {<EOF>, 'auto', 'char', 'const', 'double', 'enum', 'extern', 'float', 'inline', 'int', 'long', 'register', 'restrict', 'short', 'signed', 'static', 'struct', 'typedef', 'union', 'unsigned', 'void', 'volatile', 'BOOL', 'Class', 'bycopy', 'byref', 'id', 'IMP', 'in', 'inout', 'oneway', 'out', 'Protocol', 'SEL', 'self', 'super', '@class', '@implementation', '@interface', '@import', '@protocol', 'atomic', 'nonatomic', 'retain', '__attribute__', '__autoreleasing', '__block', '__bridge', '__bridge_retained', '__bridge_transfer', '__covariant', '__contravariant', '__deprecated', '__kindof', '__strong', TYPEOF, '__unsafe_unretained', '__unused', '__weak', NULL_UNSPECIFIED, NULLABLE, NONNULL, 'null_resettable', 'NS_INLINE', 'NS_ENUM', 'NS_OPTIONS', 'assign', 'copy', 'getter', 'setter', 'strong', 'readonly', 'readwrite', 'weak', 'unsafe_unretained', 'IBOutlet', 'IBOutletCollection', 'IBInspectable', 'IB_DESIGNABLE', IDENTIFIER}

Workaround

Remove API_AVAILABLE() prior to parsing.

const sanitizedFileContents = fileContents.replace(/ API_AVAILABLE\(.*\)\)/g, '');
const inputStream = new ANTLRInputStream(sanitizedFileContents);
const lexer = new ObjectiveCLexer(inputStream);
const tokenStream = new CommonTokenStream(lexer);
const parser = new ObjectiveCParser(tokenStream);

const listener: ObjectiveCParserListener = new ObjectiveCParserListener(...);
ParseTreeWalker.DEFAULT.walk(listener, parser.translationUnit());
Marti2203 commented 3 years ago

Hi, In the lexer there are a couple of macros that are ignored. You can also add extra ones like API_AVAILABLE, NS_SWIFT_NAME and etc.

KvanTTT commented 3 years ago

FYI, I have much more modern Objective-C grammar. Maybe I'll upload it later.