⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parser.y

📁 C-Talk is interpreted scripting language with C-like syntax and dynamic type checking. Variables in
💻 Y
字号:
%{

#include "compiler.h"
#include <malloc.h>

void yyerror(char* msg) 
{
    CtkScanner::instance.error(msg);
}

%}


%union {
    CtkToken*         tok;
    CtkProgram*       prog;
    CtkTokenList*     toks;
    CtkStmt*          stmt;
    CtkExpr*          expr;
    CtkCaseStmt*      cass;
    CtkArrayElemExpr* pair;
    ctk_integer       ival;
    ctk_real          rval;
    char*             sval;  
}

%token <tok> BREAK
             CASE
             CATCH
             CONTINUE
             DEFAULT
             DO
             ELSE
             FOR
             FUNCTION
             IDENT
             IF
             IMPORT
             NULLLITERAL
             PAR
             RETURN
             THROW
             TRY
             SYNCHRONIZED
             SWITCH
             WHILE
             ','
             ';'
             ')'
             ']'
             '{'
             '}'


%token <ival> ILITERAL
%token <rval> RLITERAL
%token <sval> SLITERAL



%right <tok> '=' SET_ADD SET_SUB SET_DIV SET_MOD SET_MUL SET_AND SET_OR SET_XOR SET_SHL SET_SHR
%left <tok>  '?' ':'
%left <tok>  LOR
%left <tok>  LAND
%left <tok>  '|'
%left <tok>  '^'
%left <tok>  '&'
%left <tok>  EQ NE 
%left <tok>  '<' LE '>' GE
%left <tok>  SHL SHR
%left <tok>  '+' '-'
%left <tok>  '%' '*' '/'
%right <tok> UPLUS UMINUS '!' '~' '$' INC DEC
%left <tok>  '(' '[' '.'

%type <toks> import_list
%type <toks> ident_list
%type <toks> not_empty_ident_list

%type <prog> program 
%type <stmt> statements
%type <stmt> stmt
%type <stmt> func_def_stmt 
%type <stmt> if_stmt
%type <stmt> for_stmt
%type <stmt> do_while_stmt
%type <stmt> while_stmt 
%type <stmt> switch_stmt
%type <stmt> continue_stmt
%type <stmt> break_stmt
%type <stmt> sync_stmt
%type <stmt> return_stmt
%type <stmt> throw_stmt
%type <stmt> try_stmt
%type <stmt> block
%type <stmt> expr_stmt
%type <stmt> empty_stmt
%type <stmt> else_branch

%type <cass> case_node_list;
%type <cass> case_node;

%type <expr> expr
%type <expr> opt_expr
%type <expr> unary_expr
%type <expr> literal
%type <expr> expr_list
%type <expr> not_empty_expr_list

%type <pair> array_initializer_list
%type <pair> not_empty_array_initializer_list
%type <pair> array_initializer

%start program

%%



program: import_list statements  { 
    $$ = new CtkProgram($1, $2);
    CtkCompiler::instance.program = $$;
}

import_list: { $$ = NULL; } | IMPORT ident_list ';' { $$ = $2; }

statements: { $$ = NULL; } | stmt statements { $1->next = $2; $$ = $1; }

stmt: func_def_stmt | if_stmt | for_stmt | do_while_stmt | while_stmt 
| switch_stmt | continue_stmt | break_stmt | sync_stmt
| return_stmt | throw_stmt | try_stmt | block | expr_stmt | empty_stmt

func_def_stmt: FUNCTION IDENT '(' ident_list ')' block { 
    $$ = new CtkFuncDef($2, $4, $6);
}

ident_list: { $$ = NULL; } | not_empty_ident_list

not_empty_ident_list: IDENT { $$ = new CtkTokenList($1, NULL); }
| IDENT ',' not_empty_ident_list { $$ = new CtkTokenList($1, $3); }

if_stmt: IF '(' expr ')' stmt else_branch { 
    $$ = new CtkIfStmt($3, $5, $6);
}

else_branch: { $$ = NULL; } | ELSE stmt { $$ = $2; }

for_stmt: FOR '(' opt_expr ';' opt_expr ';' opt_expr ')' stmt { 
    $$ = new CtkForStmt($3, $5, $7, $9);
}

opt_expr: { $$ = NULL; } | expr

do_while_stmt: DO stmt WHILE '(' expr ')' ';' { 
     $$ = new CtkDoWhileStmt($2, $5);
}

while_stmt: WHILE '(' expr ')' stmt { 
     $$ = new CtkWhileStmt($3, $5);
}

switch_stmt: SWITCH '(' expr ')' '{' case_node_list '}' { 
    $$ = new CtkSwitchStmt($3, $6);
}

case_node_list: { $$ = NULL; } | case_node case_node_list { $1->next = $2; $$ = $1; }

case_node: CASE expr ':' stmt { 
    $$ = new CtkCaseStmt($2, $4); 
}
| DEFAULT ':' stmt { 
    $$ = new CtkCaseStmt(NULL, $3); 
}
    
continue_stmt: CONTINUE ';' { 
    $$ = new CtkContinueStmt();
}

break_stmt: BREAK ';' { 
    $$ = new CtkBreakStmt();
}

return_stmt: RETURN ';' { 
    $$ = new CtkReturnStmt();
} 
| RETURN expr ';' { 
    $$ = new CtkReturnStmt($2);
} 
    
throw_stmt: THROW expr ';' { 
    $$ = new CtkThrowStmt($2); 
}

try_stmt: TRY stmt CATCH '(' IDENT ')' stmt { 
    $$ = new CtkTryStmt($2, $5, $7);
};

block: '{' statements '}' { $$ = $2; } 

expr_stmt: expr ';' { $$ = new CtkExprStmt($1); }

empty_stmt: ';' { $$ = new CtkEmptyStmt(); }

sync_stmt: SYNCHRONIZED '(' expr ')' stmt { 
    $$ = new CtkSynchronizedStmt($3, $5);
}

expr: unary_expr
| expr '+' expr { $$ = new CtkAddExpr($1, $3); } 
| expr '-' expr { $$ = new CtkSubExpr($1, $3); } 
| expr '/' expr { $$ = new CtkDivExpr($1, $3); } 
| expr '%' expr { $$ = new CtkModExpr($1, $3); } 
| expr '*' expr { $$ = new CtkMulExpr($1, $3); } 
| expr '|' expr { $$ = new CtkOrExpr($1, $3); } 
| expr '&' expr { $$ = new CtkAndExpr($1, $3); } 
| expr '^' expr { $$ = new CtkXorExpr($1, $3); } 
| expr SHL expr { $$ = new CtkShlExpr($1, $3); } 
| expr SHR expr { $$ = new CtkShrExpr($1, $3); } 

| expr EQ  expr { $$ = new CtkEqExpr($1, $3); } 
| expr NE  expr { $$ = new CtkNeExpr($1, $3); }
| expr '>' expr { $$ = new CtkGtExpr($1, $3); }
| expr GE  expr { $$ = new CtkGeExpr($1, $3); } 
| expr '<' expr { $$ = new CtkLtExpr($1, $3); }
| expr LE  expr { $$ = new CtkLeExpr($1, $3); }

| expr LAND expr { $$ = new CtkLandExpr($1, $3); }
| expr LOR expr  { $$ = new CtkLorExpr($1, $3); }

| expr '=' expr  { $$ = new CtkAssignExpr($1, $3); }
| expr SET_ADD expr { $$ = new CtkSetAddExpr($1, $3); }
| expr SET_SUB expr { $$ = new CtkSetSubExpr($1, $3); }
| expr SET_DIV expr { $$ = new CtkSetDivExpr($1, $3); }
| expr SET_MOD expr { $$ = new CtkSetModExpr($1, $3); }
| expr SET_MUL expr { $$ = new CtkSetMulExpr($1, $3); }
| expr SET_OR  expr { $$ = new CtkSetOrExpr($1, $3); }
| expr SET_XOR expr { $$ = new CtkSetXorExpr($1, $3); }
| expr SET_AND expr { $$ = new CtkSetAndExpr($1, $3); }
| expr SET_SHL expr { $$ = new CtkSetShlExpr($1, $3); }
| expr SET_SHR expr { $$ = new CtkSetShrExpr($1, $3); }
| expr '?' expr ':' expr { $$ = new CtkCondExpr($1, $3, $5); }
| PAR unary_expr '(' expr_list ')' { $$ = new CtkRunThreadExpr($2, $4); }

unary_expr: IDENT { $$ = new CtkVariable($1); }
| literal 
| '(' expr ')' { $$ = $2; }
| '+' unary_expr %prec UPLUS { $$ = $2; }
| '-' unary_expr %prec UMINUS { $$ = new CtkNegExpr($2); }
| DEC unary_expr { $$ = new CtkPreDecExpr($2); }
| INC unary_expr { $$ = new CtkPreIncExpr($2); }
| unary_expr DEC { $$ = new CtkPostDecExpr($1); }
| unary_expr INC { $$ = new CtkPostIncExpr($1); }
| '!' unary_expr { $$ = new CtkNotExpr($2); }
| '~' unary_expr { $$ = new CtkComExpr($2); }
| '$' unary_expr { $$ = new CtkEnvExpr($2); }
| '[' array_initializer_list ']' { $$ = new CtkArrayConst($2); }
| unary_expr '(' expr_list ')' { $$ = new CtkFuncCallExpr($1, $3); }
| unary_expr '[' expr ']' { $$ = new CtkArrayAccessExpr($1, $3); }
| unary_expr '.' IDENT { $$ = new CtkArrayAccessExpr($1, new CtkStringConst(ctkAllocateStringLiteral($3->name))); }



array_initializer_list: { $$ = NULL; } | not_empty_array_initializer_list

not_empty_array_initializer_list: array_initializer
| array_initializer ',' array_initializer_list { $1->next = $3; $$ = $1; }

array_initializer: expr ':' expr { $$ = new CtkArrayElemExpr($1, $3); }
|  expr { $$ = new CtkArrayElemExpr(NULL, $1); }
    
literal: SLITERAL { $$ = new CtkStringConst($1); }
| ILITERAL { $$ = new CtkIntConst($1); }
| RLITERAL { $$ = new CtkRealConst($1); }
| NULLLITERAL { $$ = new CtkNullConst(); }

expr_list: { $$ = NULL; } | not_empty_expr_list

not_empty_expr_list: expr 
| expr ',' not_empty_expr_list { $1->next = $3; $$ = $1; }


%%

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -