1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263
|
%{
// Copyright Eran Ifrah(c)
%}
%{
#include <string>
#include <stdio.h>
#include <vector>
#include "clang_output_parser_api.h"
#define YYSTYPE std::string
#define YYDEBUG 0 /* get the pretty debugging code to compile*/
#ifdef yylex
#undef yylex
#define yylex clang_yylex
#endif
extern int clang_yylex();
extern void clang_yyless(int count);
int clang_result_parse();
/** defined in grammer.l **/
extern bool clang_set_lexer_input(const std::string &in);
extern const std::string& clang_lex_get_string();
extern void clang_lex_clean();
/** the parser entry point **/
void clang_parse_string(const std::string& str);
void clang_result_error(char*);
/** read the signature **/
void clang_read_signature();
void clang_read_type_name(std::string &store);
void clang_read_entry_name(std::string &store);
/** holds the last signature read **/
static ClangEntry clang_entry;
static ClangEntryVector clangEntryVector;
extern std::string clang_result_lval;
%}
%token CLANG_COMPLETION
%token CLANG_HIDDEN
%token CLANG_DELIM_OPEN
%token CLANG_DELIM_CLOSE
%token CLANG_ARG_DELIM_OPEN
%token CLANG_ARG_DELIM_CLOSE
%token CLANG_ARG_OPT_DELIM_OPEN
%token CLANG_ARG_OPT_DELIM_CLOSE
%token CLANG_STAR
%token CLANG_AMP
%token CLANG_TILDE
%token CLANG_ENUM
%token CLANG_ANONYMOUS
%token CLANG_CLCL
%token CLANG_OP_ASSIGN
%token CLANG_OP_DOTstar
%token CLANG_OP_ARROW
%token CLANG_OP_ARROWstar
%token CLANG_OP_ICR
%token CLANG_OP_DECR
%token CLANG_OP_LS
%token CLANG_OP_RS
%token CLANG_OP_LE
%token CLANG_OP_GE
%token CLANG_OP_EQ
%token CLANG_OP_NE
%token CLANG_ELLIPSIS
%token CLANG_NAME
%token CLANG_OPERATOR
%%
parse: completion_output
| parse completion_output
;
completion_output: {clang_entry.reset();} completion_entry
| error {
//printf("CodeLite: syntax error, unexpected token '%s' found\n", clang_lex_get_string().c_str());
}
;
/* COMPLETION: AddPendingEvent : [#void#][#wxEvtHandler::#]AddPendingEvent(<#wxEvent &event#>) */
/* COMPLETION: argc : [#int#][#wxAppConsole::#]argc */
completion_entry: CLANG_COMPLETION ':' entry_name ':' type_name scope entry_name function_part
{
bool is_func = !clang_entry.signature.empty();
clang_entry.parent = $6;
clang_entry.type_name = is_func ? std::string() : clang_entry.tmp;
clang_entry.return_value = is_func ? clang_entry.tmp : std::string();
if (clang_entry.type == ClangEntry::TypeUnknown) {
if(is_func)
clang_entry.type = ClangEntry::TypeMethod;
else
clang_entry.type = ClangEntry::TypeVariable;
}
clangEntryVector.push_back(clang_entry);
}
;
any_operator: CLANG_OP_ARROW {$$ = $1;}
| CLANG_OP_ARROWstar {$$ = $1;}
| CLANG_OP_ASSIGN {$$ = $1;}
| CLANG_OP_DECR {$$ = $1;}
| CLANG_OP_DOTstar {$$ = $1;}
| CLANG_OP_EQ {$$ = $1;}
| CLANG_OP_GE {$$ = $1;}
| CLANG_OP_ICR {$$ = $1;}
| CLANG_OP_LE {$$ = $1;}
| CLANG_OP_LS {$$ = $1;}
| CLANG_OP_NE {$$ = $1;}
| CLANG_OP_RS {$$ = $1;}
| '('')' {$$ = "()";}
| '['']' {$$ = "[]";}
;
entry_name: /* empty */ { $$ = ""; }
| CLANG_NAME
{
clang_entry.name.clear();
clang_entry.name = $1;
}
| CLANG_OPERATOR any_operator
{
clang_entry.name.clear();
clang_entry.name = $1 + $2;
}
| CLANG_TILDE CLANG_NAME
{
clang_entry.name.clear();
clang_entry.name = $1 + $2;
clang_entry.type = ClangEntry::TypeDtor;
}
;
function_part: /* empty, in this case it means it is a variable */
| '(' {clang_read_signature();} ')' function_suffix
;
function_suffix: /* empty */
| CLANG_DELIM_OPEN {clang_read_type_name(clang_entry.func_suffix);} CLANG_DELIM_CLOSE
;
scope: /* empty */ {$$ = "";}
| CLANG_DELIM_OPEN CLANG_NAME CLANG_CLCL CLANG_DELIM_CLOSE {$$ = $2;}
;
type_name : CLANG_DELIM_OPEN {clang_read_type_name(clang_entry.tmp);} CLANG_DELIM_CLOSE
{
if(clang_entry.tmp.find("enum ") != std::string::npos) {
clang_entry.type = ClangEntry::TypeEnum;
}
}
| CLANG_NAME CLANG_CLCL
{
clang_entry.type = ClangEntry::TypeCtor;
}
| CLANG_NAME
{
clang_entry.type = ClangEntry::TypeClass;
}
;
%%
void clang_parse_string(const std::string& str){
clangEntryVector.clear();
clang_lex_clean();
clang_set_lexer_input(str);
clang_result_parse();
clang_lex_clean();
}
const ClangEntryVector& clang_results() {
return clangEntryVector;
}
void clang_result_error(char*){
}
void clang_read_signature() {
clang_entry.signature = "(";
int depth = 1;
while(depth > 0)
{
int ch = clang_yylex();
if(ch == 0){
break;
}
switch(ch) {
case CLANG_ARG_DELIM_OPEN:
case CLANG_ARG_DELIM_CLOSE:
case CLANG_ARG_OPT_DELIM_OPEN:
case CLANG_ARG_OPT_DELIM_CLOSE:
break;
case (int)'(':
depth++;
break;
case (int)')':
depth--;
if(depth == 0)
clang_yyless(0);
break;
default:
clang_entry.signature += clang_lex_get_string();
clang_entry.signature += " ";
break;
}
}
clang_entry.signature += ")";
}
void clang_read_type_name(std::string &store){
store.clear();
int depth = 1;
while(true)
{
int ch = clang_yylex();
if(ch == 0){
break;
}
switch(ch) {
case CLANG_DELIM_CLOSE:
clang_yyless(0);
return;
default:
store += clang_lex_get_string();
store += " ";
break;
}
}
}
void clang_read_entry_name(std::string &store){
store.clear();
while(true)
{
int ch = clang_yylex();
if(ch == 0){
break;
}
switch(ch) {
case (int)':':
clang_yyless(0);
return;
default:
store += clang_lex_get_string();
store += " ";
break;
}
}
}
|