@weixin
        
        2015-04-16T16:34:40.000000Z
        字数 4278
        阅读 1371
    compile
<INITIAL>"function" return FUNCTION;<INITIAL>"if" return IF;<INITIAL>"else" return ELSE;...<INITIAL>"-" return SUB;<INITIAL>"*" return MUL;<INITIAL>"/" return DIV;<INITIAL>"%" return MOD;<INITIAL>[A-Za-z_][A-Za-z_0-9]* {yylval.identifier = crb_create_identifier(yytext);return IDENTIFIER;}
identifier and add the memory to the interpreter->interpreter-storage 
<INITIAL>([1-9][0-9]*)|"0" {Expression *expression = crb_alloc_expression(INT_EXPRESSION);sscanf(yytext, "%d", &expression->u.int_value);yylval.expression = expression;return INT_LITERAL;}
expression and add the memory to the interpreter->interpreter-storage
<INITIAL>\" {crb_open_string_literal();BEGIN STRING_LITERAL_STATE;}
", then begin STRING_LITERAL_STATE
<STRING_LITERAL_STATE>\" {Expression *expression = crb_alloc_expression(STRING_EXPRESSION);expression->u.string_value = crb_close_string_literal();yylval.expression = expression;BEGIN INITIAL;return STRING_LITERAL;}<STRING_LITERAL_STATE>\n {crb_add_string_literal('\n');increment_line_number();}<STRING_LITERAL_STATE>\\\" crb_add_string_literal('"');<STRING_LITERAL_STATE>\\n crb_add_string_literal('\n');<STRING_LITERAL_STATE>\\t crb_add_string_literal('\t');<STRING_LITERAL_STATE>\\\\ crb_add_string_literal('\\');<STRING_LITERAL_STATE>. crb_add_string_literal(yytext[0]);
when it is in STRING_LITERAL_STATE, if see another ", then the string is closed, the allocate a string expression in interpreter. then BEGIN INITIAL, return to the initial status. 
<INITIAL>. {char buf[LINE_BUF_SIZE];if (isprint(yytext[0])) {buf[0] = yytext[0];buf[1] = '\0';} else {sprintf(buf, "0x%02x", (unsigned char)yytext[0]);}crb_compile_error(CHARACTER_INVALID_ERR,STRING_MESSAGE_ARGUMENT, "bad_char", buf,MESSAGE_ARGUMENT_END);}
. stands for any character other than the pre-defined <INITIAL> isprint is a c standard lib function, check if the char printable or not, then report compiler error.
function_definition: FUNCTION IDENTIFIER LP parameter_list RP block{crb_function_define($2, $4, $6);}| FUNCTION IDENTIFIER LP RP block{crb_function_define($2, NULL, $5);};
in crowbar, the function syntax like this : 
function func_name(param1, param2..){} or function func_name(){}
parameter_list: IDENTIFIER{$$ = crb_create_parameter($1);}| parameter_list COMMA IDENTIFIER{$$ = crb_chain_parameter($1, $3);};argument_list: expression{$$ = crb_create_argument_list($1);}| argument_list COMMA expression{$$ = crb_chain_argument_list($1, $3);};
what's the differences between parmeter and argument? here is a link : parameter vs argument 
function A(p1,p2), p1, p2 are parameters, which are part of method signature.  
b = A(arg1,arg2), arg1 and arg2 are arguments, which passed in when you call the method.  
think parameter is a parking lot, or placeholder, argument is a car. 
expression: logical_or_expression| IDENTIFIER ASSIGN expression{$$ = crb_create_assign_expression($1, $3);};logical_or_expression: logical_and_expression| logical_or_expression LOGICAL_OR logical_and_expression{$$ = crb_create_binary_expression(LOGICAL_OR_EXPRESSION, $1, $3);};
crb_create_binary_expression would create a binary tree. the workflow is like this :after checking expresison type, if the type is INT_EXPRESSION or DOUBLE_EXPRESSION, then it will crb_eval_binary_expression, this is called variable folding. 
statement: expression SEMICOLON{$$ = crb_create_expression_statement($1);}| global_statement| if_statement| while_statement| for_statement| return_statement| break_statement| continue_statement;global_statement: GLOBAL_T identifier_list SEMICOLON{$$ = crb_create_global_statement($2);};....if_statement: IF LP expression RP block{$$ = crb_create_if_statement($3, $5, NULL, NULL);}| IF LP expression RP block ELSE block{$$ = crb_create_if_statement($3, $5, NULL, $7);}| IF LP expression RP block elsif_list{$$ = crb_create_if_statement($3, $5, $6, NULL);}| IF LP expression RP block elsif_list ELSE block{$$ = crb_create_if_statement($3, $5, $6, $8);};