📄 cparse.y
字号:
;
decl-specs
: non-type-decl-specs type-spec maybe-type-decl-specs
{ $$ = combine2DeclInfo(combine2DeclInfo($1, $2), $3); }
| non-type-decl-specs type-spec
{ $$ = combine2DeclInfo($1, $2); }
| type-spec maybe-type-decl-specs
{ $$ = combine2DeclInfo($1, $2); }
| type-spec
| non-type-decl-specs
;
non-type-decl-specs
: non-type-decl-spec
| non-type-decl-specs non-type-decl-spec
{ $$ = combine2DeclInfo($1, $2); }
;
non-type-decl-spec
: storage-class-spec
| cv-qualifier
;
type-spec
: scalar-type-spec
| typedef-name
| struct-or-union-spec
{ $$ = createDeclInfoSTRUCT($1); }
| enum-spec
{ $$ = createDeclInfoENUM($1); }
;
typedef-name
: Y_TYPEDEF_NAME
{ $$ = dupDeclInfo($1->data->repr.pTypeDecl, $1->pos); zapToken($1); }
;
maybe-type-decl-specs
: non-type-decl-spec
| scalar-type-spec
| maybe-type-decl-specs non-type-decl-spec
{ $$ = combine2DeclInfo($1, $2); }
| maybe-type-decl-specs scalar-type-spec
{ $$ = combine2DeclInfo($1, $2); }
;
storage-class-spec
: Y_AUTO
{ $$ = createStgClassDeclInfo(STG_AUTO, $1);
reportError(CERR_CANT_CONVERT, "auto"); }
| Y_REGISTER
{ $$ = createStgClassDeclInfo(STG_REGISTER, $1);
reportError(CERR_CANT_CONVERT, "register"); }
| Y_EXTERN
{ $$ = createStgClassDeclInfo(STG_EXTERN, $1); }
| Y_STATIC
{ $$ = createStgClassDeclInfo(STG_STATIC, $1);
reportError(CERR_CANT_CONVERT, "static"); }
| Y_TYPEDEF
{ $$ = createStgClassDeclInfo(STG_TYPEDEF, $1); }
;
scalar-type-spec
: Y_VOID
{ $$ = createDeclInfoSCALAR(STM_VOID, $1->pos);
$1->pos = NULL; zapToken($1); }
| Y_CHAR
{ $$ = createDeclInfoSCALAR(STM_CHAR, $1->pos);
$1->pos = NULL; zapToken($1); }
| Y_SHORT
{ $$ = createDeclInfoSCALAR(STM_SHORT, $1->pos);
$1->pos = NULL; zapToken($1); }
| Y_INT
{ $$ = createDeclInfoSCALAR(STM_INT, $1->pos);
$1->pos = NULL; zapToken($1); }
| Y_LONG
{ $$ = createDeclInfoSCALAR(STM_LONG, $1->pos);
$1->pos = NULL; zapToken($1); }
| Y_FLOAT
{ $$ = createDeclInfoSCALAR(STM_FLOAT, $1->pos);
$1->pos = NULL; zapToken($1); }
| Y_DOUBLE
{ $$ = createDeclInfoSCALAR(STM_DOUBLE, $1->pos);
$1->pos = NULL; zapToken($1); }
| Y_SIGNED
{ $$ = createDeclInfoSCALAR(STM_SIGNED, $1->pos);
$1->pos = NULL; zapToken($1); }
| Y_UNSIGNED
{ $$ = createDeclInfoSCALAR(STM_UNSIGNED, $1->pos);
$1->pos = NULL; zapToken($1); }
;
struct-or-union-spec
: struct-or-union struct-id struct-or-union-body
{ $$ = createDeclStructInfo($1, $2, $3); }
| struct-or-union struct-or-union-body
{ $$ = createDeclStructInfo($1, NULL, $2); }
| struct-or-union struct-id
{ $$ = createDeclStructInfo($1, $2, NULL); }
;
struct-id
: Y_ID
| Y_TYPEDEF_NAME
;
struct-or-union
: Y_STRUCT
| Y_UNION
;
struct-or-union-body
: Y_LEFT_BRACE struct-decl-list Y_RIGHT_BRACE
{
$$ = createDeclStructBody($2, $3->pos);
$3->pos = NULL; zapTokens2($1, $3);
}
;
struct-decl-list
: struct-decl
{ $$ = createDeclList($1); }
| struct-decl-list struct-decl
{ $$ = addDeclList($1, $2); }
| struct-decl-list error
{ recoverError(); $$ = $1; }
;
struct-decl
: decl-specs Y_SEMICOLON
{ $$ = addDeclInfoDclrList($1, NULL); zapToken($2); }
| decl-specs struct-declarator-list Y_SEMICOLON
{ $$ = addDeclInfoDclrList($1, $2); zapToken($3); }
;
struct-declarator-list
: struct-declarator
{ $$ = createDclrList($1); }
| struct-declarator-list Y_COMMA struct-declarator
{ $$ = addDclrList($1, $3); zapToken($2); }
;
struct-declarator
: declarator
| declarator Y_COLON constant-expression
{
reportError(CERR_CANT_CONVERT_BIT_FIELDS);
$$ = $1;
zapToken($2); zapCTree($3);
}
;
enum-spec
: Y_ENUM identifier Y_LEFT_BRACE enum-list Y_RIGHT_BRACE
{ $$ = createDeclEnum($1, $4); zapTokens3($2, $3, $5); }
| Y_ENUM identifier
{ $$ = createDeclEnum($1, NULL); zapToken($2); }
| Y_ENUM Y_LEFT_BRACE enum-list Y_RIGHT_BRACE
{ $$ = createDeclEnum($1, $3); zapTokens2($2, $4); }
;
enum-list
: enum-list-collect
{ $$ = finishEnumListCreation($1); }
| enum-list-collect Y_COMMA /* Watcom C extension */
{ $$ = finishEnumListCreation($1); }
;
enum-list-collect
: enumerator
{ $$ = createEnumList($1); }
| enum-list-collect comma-and-enumerator
{ $$ = addEnumList($1, $2); }
| enum-list-collect error
{ recoverError(); $$ = $1; }
;
comma-and-enumerator
: Y_COMMA enumerator
{ $$ = addEnumElemBegPunct($2); zapToken($1); }
;
enumerator
: identifier
{ $$ = createEnumElem($1, NULL, NULL); }
| identifier Y_EQUAL constant-expression
{ $$ = createEnumElem($1, $2, $3); }
;
cv-qualifier
: Y_CONST
{ reportError(CERR_CANT_CONVERT_QUALIFIER);
$$ = createQualifierDeclInfo(STY_CONST, $1->pos);
$1->pos = NULL; zapToken($1); }
| Y_VOLATILE
{ reportError(CERR_CANT_CONVERT_QUALIFIER);
$$ = createQualifierDeclInfo(STY_VOLATILE, $1->pos);
$1->pos = NULL; zapToken($1); }
;
type-name
: decl-specs
{ $$ = createCTreeRoot(createDeclInfoLabel($1)); }
| decl-specs declarator-no-id
{ $$ = createCTreeRoot(createDeclInfoLabel(addDeclDclr($1, $2))); }
;
literal
: strings
| Y_NUMBER
{ $$ = createCTreeRoot(createTokenLabel($1)); }
;
strings
: strings single-string
{
$$ = createCTree2(createConstr0Label(LABCT_STRINGS), $1, $2);
}
| single-string
{ $$ = $1; }
;
single-string
: Y_STRING
{ $$ = createCTreeRoot(createTokenLabel($1)); }
;
declarator-id
: identifier
| Y_TYPEDEF_NAME
;
declarator
: pragma-modifier declarator
{ $$ = addDclrPragmaModifier($2, $1); }
| mem-modifier declarator
{ $$ = addDclrMemModifier($2, $1); }
| ptr-modifier declarator
{ $$ = addDclrPtrModifier($2, $1); }
| actual-declarator
{ $$ = $1; }
;
actual-declarator
: declarator-id
{ $$ = createDclr($1); }
| Y_LEFT_PAREN declarator Y_RIGHT_PAREN
{ $$ = $2; zapTokens2($1, $3); }
| actual-declarator Y_LEFT_BRACKET constant-expression Y_RIGHT_BRACKET
{ $$ = addDclrArray($1, $2, $3, $4); }
| actual-declarator Y_LEFT_BRACKET Y_RIGHT_BRACKET
{ $$ = addDclrArray($1, $2, NULL, $3); }
| actual-declarator Y_LEFT_PAREN abstract-args Y_RIGHT_PAREN
{ $$ = addDclrFuncArgs($1, $2, $3, $4); }
;
declarator-no-id
: pragma-modifier declarator-no-id
{ $$ = addDclrPragmaModifier($2, $1); }
| pragma-modifier
{ $$ = addDclrPragmaModifier(createDclr(NULL), $1); }
| mem-modifier declarator-no-id
{ $$ = addDclrMemModifier($2, $1); }
| mem-modifier
{ $$ = addDclrMemModifier(createDclr(NULL), $1); }
| ptr-modifier declarator-no-id
{ $$ = addDclrPtrModifier($2, $1); }
| ptr-modifier
{ $$ = addDclrPtrModifier(createDclr(NULL), $1); }
| actual-declarator-no-id
{ $$ = $1; }
;
actual-declarator-no-id
: Y_LEFT_PAREN declarator-no-id Y_RIGHT_PAREN
{ $$ = $2; zapTokens2($1, $3); }
| actual-declarator-no-id Y_LEFT_BRACKET Y_RIGHT_BRACKET
{ $$ = addDclrArray($1, $2, NULL, $3); }
| actual-declarator-no-id Y_LEFT_BRACKET constant-expression Y_RIGHT_BRACKET
{ $$ = addDclrArray($1, $2, $3, $4); }
| Y_LEFT_BRACKET Y_RIGHT_BRACKET
{ $$ = addDclrArray(createDclr(NULL), $1, NULL, $2); }
| Y_LEFT_BRACKET constant-expression Y_RIGHT_BRACKET
{ $$ = addDclrArray(createDclr(NULL), $1, $2, $3); }
| actual-declarator-no-id Y_LEFT_PAREN abstract-args Y_RIGHT_PAREN
{ $$ = addDclrFuncArgs($1, $2, $3, $4); }
| Y_LEFT_PAREN abstract-args Y_RIGHT_PAREN
{ $$ = addDclrFuncArgs(createDclr(NULL), $1, $2, $3); }
;
ptr-modifier
: Y_TIMES cv-qualifiers-opt
{ $$ = createDclrPtr($1, $2); }
;
mem-modifier
: Y___NEAR
| Y___FAR
| Y___FAR16
| Y___HUGE
;
pragma-modifier
: Y___CDECL
| Y___PASCAL
| Y___FORTRAN
| Y__SYSCALL
| Y___STDCALL
;
cv-qualifiers-opt
: /* nothing */
{ $$ = STY_NULL; }
| Y_CONST
{ reportError(CERR_CANT_CONVERT_QUALIFIER);
$$ = STY_CONST; zapToken($1); }
| Y_CONST Y_VOLATILE
{ reportError(CERR_CANT_CONVERT_QUALIFIER);
$$ = STY_CONST | STY_VOLATILE; zapTokens2($1, $2); }
| Y_VOLATILE
{ reportError(CERR_CANT_CONVERT_QUALIFIER);
$$ = STY_VOLATILE; zapToken($1); }
| Y_VOLATILE Y_CONST
{ reportError(CERR_CANT_CONVERT_QUALIFIER);
$$ = STY_CONST | STY_VOLATILE; zapTokens2($1, $2); }
;
abstract-args
: /* nothing */
{ $$ = createSLList(); }
| arg-decl-list
| arg-decl-list Y_COMMA dot-dot-dot-decl
{ addDeclPunct($3, $2); $$ = addDeclList($1, $3 ); }
| dot-dot-dot-decl
{ $$ = createDeclList($1); }
;
arg-decl-list
: arg-decl-elem
{ $$ = createDeclList($1); }
| arg-decl-list Y_COMMA arg-decl-elem
{ addDeclPunct($3, $2); $$ = addDeclList($1, $3 ); }
;
arg-decl-elem
: decl-specs
{ $$ = $1; }
| decl-specs declarator
{ $$ = addDeclDclr($1, $2); }
| decl-specs declarator-no-id
{ $$ = addDeclDclr($1, $2); }
;
dot-dot-dot-decl
: Y_DOT_DOT_DOT
{ $$ = createDeclInfoSCALAR(STM_DOT_DOT_DOT, $1->pos);
$1->pos = NULL; zapToken($1); }
;
identifier
: Y_ID
{ $$ = $1; }
;
/* NOTE: There is an ambiguity in C:
typedef int F, INT; static F(INT);
This is resolved by redefining F as a function, not by redefining INT
to be of type "static F"
*/
/*==========================================================================*/
%%
static pToken savedToken;
int cerror(char *str) {
str = str;
return 0;
}
void cparseInterface(void) {
savedToken = NULL;
cparse();
}
static int clex(void) {
int retval;
int dummy;
if (savedToken != NULL) {
clval.token = savedToken;
savedToken = NULL;
} else {
clval.token = getExpandToken(EXP_OP_EXPAND, &dummy);
}
while (getTokDataType(clval.token->data) == TT_PREPROCESSOR) {
if (clval.token->data->code == Y_PRE_NEWLINE) {
//This is an optimization
zapToken(clval.token);
} else {
preparseInterface(clval.token);
}
clval.token = getExpandToken(1, &dummy);
}
retval = clval.token->data->code;
return retval;
}
#define cclearin cchar = -1
// We have to copy yacc def'n of cclearin since
// yacc puts recoverError() function before it declares
// 'cclearin'. If yacc's def'n ever changes,
// we will get a redefinition error.
#define CLEARIN cclearin // Needed for recoverError
static void recoverError(void) {
pToken tok;
int code;
pSLList context = createSLList();
int recordMaxTok = 15;
char *s1, *s2;
for (tok = clval.token, code = tok->data->code;
code != Y_SEMICOLON && code != Y_EOF && code != Y_RIGHT_BRACE &&
getTokDataType(tok->data) != TT_PREPROCESSOR;
clex(), tok = clval.token, code = tok->data->code)
{
if (recordMaxTok-- > 0) {
addSLListElem(context, tok);
}
}
s1 = getTokListString(context);
s2 = staticGetTokenStr(tok, 0);
reportError(RERR_CPARSE_WITH_CONTEXT, s1, s2);
zapSLList(context, zapToken);
CLEARIN;
savedToken = tok;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -