Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 51 additions & 16 deletions src/grammar.y
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,23 @@ int yyerror(const char *s);
int int_value;
struct Expression* expression;
struct Statement *statement;
struct StatementList *statement_list;
struct Block *block;
struct Elseif *elseif;
}

%token <int_value> BOOL_LITERAL
%token <double_value> DOUBLE_LITERAL
%token <int_value> INT_LITERAL
%token <identifier> IDENTIFIER;
%token FUNCTION IF ELSE FOR RETURN BREAK CONTINUE NIL
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个只是符号,在lex中实际匹配的就是"func"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

嗯嗯,lex里看到了,删除了


%type <expression> expr bool_expr
Copy link
Copy Markdown
Contributor

@boomyl boomyl Jul 20, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

逻辑没啥问题,就是感觉摆在一起有些突兀,应该是一般表达式,bool表达式

%type <statement> stmt if_stmt
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

同上,一般语句,if语句

%type <statement_list> stmt_list
%type <block> block
%type <elseif> elseif elseif_list

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

%nonassoc '\n' 不要了?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

之前发现会冲突,加了这个,文法改了之后没有这个问题

%nonassoc '\n'
%nonassoc '='
%left AND OR
%nonassoc EQ NE
Expand All @@ -31,18 +40,39 @@ int yyerror(const char *s);
%nonassoc MINUS
%nonassoc NOT

%type <expression> expr
%type <statement> stmt

%%

stmt_list:
stmt
| stmt_list stmt
stmt {$$ = allocStatementList($1); }
| stmt_list '\n' stmt {$$ = chainStatementList($1, $3); }
;

stmt:
expr '\n' { printExprValue(evalExpression($1)); }
expr { printExprValue(evalExpression($1)); }
| IDENTIFIER '=' expr { $$ = allocAssignStatement($1, $3); }
| block { $$ = allocBlockStatement($1); }
| if_stmt
;

if_stmt:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这4类if场景最好有个示意图,$有些晕

IF '(' bool_expr ')' block { $$ = allocIfStatement($3, $5, NULL, NULL); }
| IF '(' bool_expr ')' block ELSE block { $$ = allocIfStatement($3, $5, NULL, $7); }
| IF '(' bool_expr ')' block elseif_list { $$ = allocIfStatement($3, $5, $6, NULL); }
| IF '(' bool_expr ')' block elseif_list ELSE block { $$ = allocIfStatement($3, $5, $6, $8); }
;

elseif_list:
elseif
| elseif_list elseif { $$ = chainElseifList($1, $2); }
;

elseif:
ELSE IF '(' bool_expr ')' block { $$ = allocElseif($4, $6); }
;

block:
'{' stmt_list '}' { $$ = allocBlock($2); }
| '{' '}' { $$ = allocBlock(NULL); }
;

expr:
Expand All @@ -54,18 +84,23 @@ expr:
| expr '-' expr { $$ = allocBinaryExpression(SUB_EXPRESSION, $1, $3); }
| expr '*' expr { $$ = allocBinaryExpression(MUL_EXPRESSION, $1, $3); }
| expr '/' expr { $$ = allocBinaryExpression(DIV_EXPRESSION, $1, $3); }
| expr '>' expr { $$ = allocBinaryExpression(GT_EXPRESSION, $1, $3); }
| expr GE expr { $$ = allocBinaryExpression(GE_EXPRESSION, $1, $3); }
| expr '<' expr { $$ = allocBinaryExpression(LT_EXPRESSION, $1, $3); }
| expr LE expr { $$ = allocBinaryExpression(LE_EXPRESSION, $1, $3); }
| expr EQ expr { $$ = allocBinaryExpression(EQ_EXPRESSION, $1, $3); }
| expr NE expr { $$ = allocBinaryExpression(NE_EXPRESSION, $1, $3); }
| expr AND expr { $$ = allocBinaryExpression(AND_EXPRESSION, $1, $3); }
| expr OR expr { $$ = allocBinaryExpression(OR_EXPRESSION, $1, $3); }
| '!' expr %prec NOT { $$ = allocUnaryExpression(NOT_EXPRESSION, $2); }
| '-' expr %prec MINUS { $$ = allocUnaryExpression(MINUS_EXPRESSION, $2); }
| '(' expr ')' { $$ = $2; }
| bool_expr
;

bool_expr:
expr '>' expr { $$ = allocBinaryExpression(GT_EXPRESSION, $1, $3); }
| expr GE expr { $$ = allocBinaryExpression(GE_EXPRESSION, $1, $3); }
| expr '<' expr { $$ = allocBinaryExpression(LT_EXPRESSION, $1, $3); }
| expr LE expr { $$ = allocBinaryExpression(LE_EXPRESSION, $1, $3); }
| expr EQ expr { $$ = allocBinaryExpression(EQ_EXPRESSION, $1, $3); }
| expr NE expr { $$ = allocBinaryExpression(NE_EXPRESSION, $1, $3); }
| expr AND expr { $$ = allocBinaryExpression(AND_EXPRESSION, $1, $3); }
| expr OR expr { $$ = allocBinaryExpression(OR_EXPRESSION, $1, $3); }
| '!' expr %prec NOT { $$ = allocUnaryExpression(NOT_EXPRESSION, $2); }
;

%%

int yyerror(char const *str) {
Expand Down
22 changes: 15 additions & 7 deletions src/lex.l
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,24 @@

%%

[+\-*/\(\)<>!\n] {
[+\-*/\(\)<>!{}\n] {
return *yytext;
}

">=" return GE;
"<=" return LE;
"==" return EQ;
"!=" return NE;
"&&" return AND;
"||" return OR;
">=" return GE;
"<=" return LE;
"==" return EQ;
"!=" return NE;
"&&" return AND;
"||" return OR;
"if" return IF;
"else" return ELSE;
"for" return FOR;
"nil" return NIL;
"func" return FUNCTION;
"return" return RETURN;
"break" return BREAK;
"continue" return CONTINUE;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

漏了lock?


"true"|"false" {
yylval.int_value = strcmp(yytext, "false");
Expand Down
77 changes: 75 additions & 2 deletions src/summoner.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,88 @@ Expression *allocBinaryExpression(ExpressionKind kind, Expression *left, Express
return expr;
}

Statement *allocStatement(StatementKind kind) {
Statement *allocStatement(StatementKind kind)
{
Statement *stmt = malloc(sizeof(Statement));
stmt->kind = kind;
return stmt;
}

Statement *allocAssignStatement(char *variable, Expression *operand) {
Statement *allocAssignStatement(char *variable, Expression *operand)
{
Statement *stmt = allocStatement(ASSIGN_STATEMENT);
AssignStatement *assign_s = malloc(sizeof(AssignStatement));
stmt->u.assign_s = assign_s;
return stmt;
}

Statement *allocIfStatement(Expression *condition, Block *then_block, Elseif *elseif_list, Block *else_block)
{
Statement *stmt = allocStatement(IF_STATEMENT);
IfStatement *if_s = malloc(sizeof(IfStatement));
if_s->condition = condition;
if_s->then_block = then_block;
if_s->elseif_list = elseif_list;
if_s->else_block = else_block;
stmt->u.if_s = if_s;
return stmt;
}

Statement *allocBlockStatement(Block *block)
{
Statement *stmt = allocStatement(BLOCK_STATEMENT);
stmt->u.block_s = block;
return stmt;
}

StatementList *allocStatementList(Statement *statement)
{
StatementList *stmt_list = malloc(sizeof(StatementList));
stmt_list->statement = statement;
return stmt_list;
}

StatementList *chainStatementList(StatementList *list, Statement *statement)
{
if (list == NULL)
{
return allocStatementList(statement);
}

StatementList *pos;
for (pos = list; pos->next; pos = pos->next)
;

pos->next = allocStatementList(statement);
return list;
}

Elseif *allocElseif(Expression *condition, Block *block)
{
Elseif *elseif = malloc(sizeof(Elseif));
elseif->condition = condition;
elseif->block = block;
return elseif;
}

Elseif *chainElseifList(Elseif *list, Elseif *elseif)
{
if (list == NULL)
{
return elseif;
}

Elseif *pos;
for (pos = list; pos->next; pos = pos->next)
;

pos->next = elseif;
return list;
}

Block *allocBlock(StatementList *list)
{
Block *block = malloc(sizeof(Block));
block->statemen_list = list;
return block;
}
34 changes: 31 additions & 3 deletions src/summoner.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,6 @@ typedef enum
NOT_EXPRESSION, /* ! */
} ExpressionKind;

typedef struct BinaryExpression BinaryExpression;

typedef struct Expression
{
ExpressionKind kind;
Expand All @@ -56,7 +54,7 @@ typedef struct Expression
int int_value;
double double_value;
char *identifier;
BinaryExpression *binary_expression;
struct BinaryExpression *binary_expression;
struct Expression *unary_expression;
} u;

Expand All @@ -79,6 +77,7 @@ Expression *allocBinaryExpression(ExpressionKind kind, Expression *left, Express
typedef enum
{
ASSIGN_STATEMENT = 1,
BLOCK_STATEMENT,
IF_STATEMENT,
FOR_STATEMENT,
RETURN_STATEMENT,
Expand All @@ -98,6 +97,8 @@ typedef struct Statement
union
{
AssignStatement *assign_s;
struct Block *block_s;
struct IfStatement *if_s;
} u;
} Statement;

Expand All @@ -107,7 +108,34 @@ typedef struct StatementList
struct StatementList *next;
} StatementList;

typedef struct Block
{
StatementList *statemen_list;
} Block;

typedef struct Elseif
{
Expression *condition;
Block *block;
struct Elseif *next;
} Elseif;

typedef struct IfStatement
{
Expression *condition;
Block *then_block;
Elseif *elseif_list;
Block *else_block;
} IfStatement;

Statement *allocStatement(StatementKind kind);
Statement *allocAssignStatement(char *variable, Expression *operand);
Statement *allocBlockStatement(Block *block);
Statement *allocIfStatement(Expression *condition, Block *then_block, Elseif *elseif_list, Block *else_block);
StatementList *allocStatementList(Statement *statement);
StatementList *chainStatementList(StatementList *list, Statement *statement);
Elseif *allocElseif(Expression *condition, Block *block);
Elseif *chainElseifList(Elseif *list, Elseif *elseif);
Block *allocBlock(StatementList *list);

#endif