Preprocessor/parser improvements
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@904 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
34758852c2
commit
fc84a3085c
4 changed files with 97 additions and 62 deletions
|
|
@ -373,6 +373,7 @@ yylex1(void) {
|
|||
if (strcmp(yytext,"static") == 0) return(STATIC);
|
||||
if (strcmp(yytext,"extern") == 0) return(EXTERN);
|
||||
if (strcmp(yytext,"const") == 0) return(CONST);
|
||||
if (strcmp(yytext,"typedef") == 0) return(TYPEDEF);
|
||||
if (strcmp(yytext,"struct") == 0) {
|
||||
yylval.tok.text = NewString(yytext);
|
||||
return(STRUCT);
|
||||
|
|
@ -389,47 +390,49 @@ yylex1(void) {
|
|||
if (strcmp(yytext,"volatile") == 0) return(lparse_yylex());
|
||||
|
||||
/* SWIG directives */
|
||||
if (strcmp(yytext,"%module") == 0) return(MODULE);
|
||||
if (strcmp(yytext,"%constant") == 0) return (CONSTANT);
|
||||
if (strcmp(yytext,"%type") == 0) return (TYPE);
|
||||
if (strcmp(yytext,"%init") == 0) return(INIT);
|
||||
if (strcmp(yytext,"%wrapper") == 0) return(WRAPPER);
|
||||
if (strcmp(yytext,"%runtime") == 0) return(RUNTIME);
|
||||
if (strcmp(yytext,"%readonly") == 0) return(READONLY);
|
||||
if (strcmp(yytext,"%readwrite") == 0) return(READWRITE);
|
||||
if (strcmp(yytext,"%name") == 0) return(NAME);
|
||||
if (strcmp(yytext,"%rename") == 0) return(RENAME);
|
||||
if (strcmp(yytext,"%includefile") == 0) return(INCLUDE);
|
||||
if (strcmp(yytext,"%externfile") == 0) return(WEXTERN);
|
||||
if (strcmp(yytext,"%checkout") == 0) return(CHECKOUT);
|
||||
if (strcmp(yytext,"%macro") == 0) return(MACRO);
|
||||
if (strcmp(yytext,"%section") == 0) return(SECTION);
|
||||
if (strcmp(yytext,"%subsection") == 0) return(SUBSECTION);
|
||||
if (strcmp(yytext,"%subsubsection") == 0) return(SUBSUBSECTION);
|
||||
if (strcmp(yytext,"%title") == 0) return(TITLE);
|
||||
if (strcmp(yytext,"%style") == 0) return(STYLE);
|
||||
if (strcmp(yytext,"%localstyle") == 0) return(LOCALSTYLE);
|
||||
if (strcmp(yytext,"%typedef") == 0) return(TYPEDEF);
|
||||
if (strcmp(yytext,"typedef") == 0) return(TYPEDEF);
|
||||
if (strcmp(yytext,"%alpha") == 0) return(ALPHA_MODE);
|
||||
if (strcmp(yytext,"%raw") == 0) return(RAW_MODE);
|
||||
if (strcmp(yytext,"%text") == 0) return(TEXT);
|
||||
if (strcmp(yytext,"%native") == 0) return(NATIVE);
|
||||
if (strcmp(yytext,"%disabledoc") == 0) return(DOC_DISABLE);
|
||||
if (strcmp(yytext,"%enabledoc") == 0) return(DOC_ENABLE);
|
||||
if (strcmp(yytext,"%pragma") == 0) return(PRAGMA);
|
||||
if (strcmp(yytext,"%addmethods") == 0) return(ADDMETHODS);
|
||||
if (strcmp(yytext,"%inline") == 0) return(INLINE);
|
||||
if (strcmp(yytext,"%typemap") == 0) return(TYPEMAP);
|
||||
if (strcmp(yytext,"%except") == 0) return(EXCEPT);
|
||||
if (strcmp(yytext,"%importfile") == 0) return(IMPORT);
|
||||
if (strcmp(yytext,"%echo") == 0) return(ECHO);
|
||||
if (strcmp(yytext,"%new") == 0) return(NEW);
|
||||
if (strcmp(yytext,"%apply") == 0) return(APPLY);
|
||||
if (strcmp(yytext,"%clear") == 0) return(CLEAR);
|
||||
if (strcmp(yytext,"%doconly") == 0) return(DOCONLY);
|
||||
if (strcmp(yytext,"%map") == 0) return(MAP);
|
||||
if (yytext[0] == '%') {
|
||||
if (strcmp(yytext,"%module") == 0) return(MODULE);
|
||||
if (strcmp(yytext,"%constant") == 0) return (CONSTANT);
|
||||
if (strcmp(yytext,"%type") == 0) return (TYPE);
|
||||
if (strcmp(yytext,"%init") == 0) return(INIT);
|
||||
if (strcmp(yytext,"%wrapper") == 0) return(WRAPPER);
|
||||
if (strcmp(yytext,"%runtime") == 0) return(RUNTIME);
|
||||
if (strcmp(yytext,"%readonly") == 0) return(READONLY);
|
||||
if (strcmp(yytext,"%readwrite") == 0) return(READWRITE);
|
||||
if (strcmp(yytext,"%name") == 0) return(NAME);
|
||||
if (strcmp(yytext,"%rename") == 0) return(RENAME);
|
||||
if (strcmp(yytext,"%includefile") == 0) return(INCLUDE);
|
||||
if (strcmp(yytext,"%externfile") == 0) return(WEXTERN);
|
||||
if (strcmp(yytext,"%insert") == 0) return (INSERT);
|
||||
if (strcmp(yytext,"%checkout") == 0) return(CHECKOUT);
|
||||
if (strcmp(yytext,"%macro") == 0) return(MACRO);
|
||||
if (strcmp(yytext,"%section") == 0) return(SECTION);
|
||||
if (strcmp(yytext,"%subsection") == 0) return(SUBSECTION);
|
||||
if (strcmp(yytext,"%subsubsection") == 0) return(SUBSUBSECTION);
|
||||
if (strcmp(yytext,"%title") == 0) return(TITLE);
|
||||
if (strcmp(yytext,"%style") == 0) return(STYLE);
|
||||
if (strcmp(yytext,"%localstyle") == 0) return(LOCALSTYLE);
|
||||
if (strcmp(yytext,"%typedef") == 0) return(TYPEDEF);
|
||||
|
||||
if (strcmp(yytext,"%alpha") == 0) return(ALPHA_MODE);
|
||||
if (strcmp(yytext,"%raw") == 0) return(RAW_MODE);
|
||||
if (strcmp(yytext,"%text") == 0) return(TEXT);
|
||||
if (strcmp(yytext,"%native") == 0) return(NATIVE);
|
||||
if (strcmp(yytext,"%disabledoc") == 0) return(DOC_DISABLE);
|
||||
if (strcmp(yytext,"%enabledoc") == 0) return(DOC_ENABLE);
|
||||
if (strcmp(yytext,"%pragma") == 0) return(PRAGMA);
|
||||
if (strcmp(yytext,"%addmethods") == 0) return(ADDMETHODS);
|
||||
if (strcmp(yytext,"%inline") == 0) return(INLINE);
|
||||
if (strcmp(yytext,"%typemap") == 0) return(TYPEMAP);
|
||||
if (strcmp(yytext,"%except") == 0) return(EXCEPT);
|
||||
if (strcmp(yytext,"%importfile") == 0) return(IMPORT);
|
||||
if (strcmp(yytext,"%echo") == 0) return(ECHO);
|
||||
if (strcmp(yytext,"%new") == 0) return(NEW);
|
||||
if (strcmp(yytext,"%apply") == 0) return(APPLY);
|
||||
if (strcmp(yytext,"%clear") == 0) return(CLEAR);
|
||||
if (strcmp(yytext,"%doconly") == 0) return(DOCONLY);
|
||||
if (strcmp(yytext,"%map") == 0) return(MAP);
|
||||
}
|
||||
/* Have an unknown identifier, as a last step, we'll */
|
||||
/* do a typedef lookup on it. */
|
||||
yylval.tok.text = NewString(yytext);
|
||||
|
|
|
|||
|
|
@ -571,21 +571,25 @@ except_directive: EXCEPT LPAREN ID RPAREN LBRACE {
|
|||
}
|
||||
;
|
||||
|
||||
pragma_directive : PRAGMA ID pragma_arg {
|
||||
$$ = new_node("pragmadirective",$1.filename,$1.line);
|
||||
pragma_directive : PRAGMA idstring pragma_arg SEMI {
|
||||
$$ = new_node("pragma",$1.filename,$1.line);
|
||||
Setattr($$,ATTR_NAME,$2.text);
|
||||
Setattr($$,ATTR_VALUE,$3.text);
|
||||
}
|
||||
| PRAGMA LPAREN ID RPAREN ID pragma_arg {
|
||||
$$ = new_node("pragmadirective",$1.filename,$1.line);
|
||||
| PRAGMA LPAREN idstring RPAREN idstring pragma_arg SEMI {
|
||||
$$ = new_node("pragma",$1.filename,$1.line);
|
||||
Setattr($$,ATTR_NAME,$5.text);
|
||||
Setattr($$,"lang",$3.text);
|
||||
Setattr($$,ATTR_VALUE,$6.text);
|
||||
}
|
||||
;
|
||||
|
||||
pragma_arg : EQUAL definetype {
|
||||
pragma_arg : definetype {
|
||||
$$.text = $1.text;
|
||||
}
|
||||
| EQUAL definetype {
|
||||
$$.text = $2.text;
|
||||
/* print warning message here */
|
||||
}
|
||||
| empty {
|
||||
$$.text = 0;
|
||||
|
|
|
|||
|
|
@ -69,22 +69,26 @@ tag : "new"
|
|||
syntax : %new decl
|
||||
attributes : None
|
||||
|
||||
tag : "headerblock"
|
||||
syntax : %{ code %}
|
||||
attributes : "code" - Included text
|
||||
|
||||
tag : "wrapperblock"
|
||||
syntax : %{ code %}
|
||||
attributes : "code" - Included code
|
||||
|
||||
tag : "initblock"
|
||||
syntax : %{ code %}
|
||||
attributes : "code" - Included code
|
||||
tag : "insert"
|
||||
syntax : %insert(section) "filename"
|
||||
%insert(section) %{ code %}
|
||||
%{ code %} Note: same as %insert("header") %{ code %}
|
||||
%inline %{ code %} Note: same as %insert("header") %{ code %}
|
||||
attributes : "section" - Code section
|
||||
"filename" - File to include (if given)
|
||||
"code" - Code to include (if given)
|
||||
|
||||
|
||||
tag : "pragma"
|
||||
syntax : %pragma name [ value ];
|
||||
%pragma(lang) name [ value ];
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -283,19 +283,21 @@ find_args(DOHString *s)
|
|||
DOHList *args;
|
||||
DOHString *str;
|
||||
int c, level;
|
||||
long pos;
|
||||
|
||||
/* Create a new list */
|
||||
args = NewList();
|
||||
copy_location(s,args);
|
||||
|
||||
/* First look for a '(' */
|
||||
pos = Tell(s);
|
||||
skip_whitespace(s,0);
|
||||
|
||||
/* Now see if the next character is a '(' */
|
||||
c = Getc(s);
|
||||
if (c != '(') {
|
||||
/* Not a macro, bail out now! */
|
||||
cpp_error(Getfile(s),Getline(s),"Missing macro arguments\n");
|
||||
Seek(s,pos, SEEK_SET);
|
||||
return args;
|
||||
}
|
||||
c = Getc(s);
|
||||
|
|
@ -401,12 +403,14 @@ expand_macro(DOHString_or_char *name, DOHList *args)
|
|||
ns = NewString("");
|
||||
Printf(ns,"%s",name);
|
||||
if (args) {
|
||||
Putc('(',ns);
|
||||
if (Len(args))
|
||||
Putc('(',ns);
|
||||
for (i = 0; i < Len(args); i++) {
|
||||
Printf(ns,"%s",Getitem(args,i));
|
||||
if (i < (Len(args) -1)) Putc(',',ns);
|
||||
}
|
||||
Putc(')',ns);
|
||||
if (i)
|
||||
Putc(')',ns);
|
||||
}
|
||||
return ns;
|
||||
}
|
||||
|
|
@ -456,6 +460,26 @@ expand_macro(DOHString_or_char *name, DOHList *args)
|
|||
Printf(tempa,"\"%s\"",arg);
|
||||
Replace(ns, temp, tempa, DOH_REPLACE_ANY);
|
||||
}
|
||||
|
||||
/* Non-standard macro expansion. The value `x` is replaced by a quoted
|
||||
version of the argument except that if the argument is already quoted
|
||||
nothing happens */
|
||||
|
||||
if (strstr(Char(ns),"`")) {
|
||||
String *rep;
|
||||
char *c;
|
||||
Clear(temp);
|
||||
Printf(temp,"`%s`",aname);
|
||||
c = Char(arg);
|
||||
if (*c == '\"') {
|
||||
rep = arg;
|
||||
} else {
|
||||
Clear(tempa);
|
||||
Printf(tempa,"\"%s\"",arg);
|
||||
rep = tempa;
|
||||
}
|
||||
Replace(ns,temp,rep, DOH_REPLACE_ANY);
|
||||
}
|
||||
Replace(ns, aname, arg, DOH_REPLACE_ID);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue