我们先来想一下语法
一般脚本语言不需要定义类型直接在赋值的时候确定
- 我们主要考虑一下变量的类型
a = 1;
b = 1.1;
c = "str";
一般来讲,我们使用这三种类型,整形,浮点型,字符串型
不过我们以后还可能使用原生类型等
- 变量的基本运算和其他语言基本相同
a = b + 12.4;
c = "hehe" + a + "haha"
- 函数定义 我们可以模仿一下js的函数定义方式,不过变量使用的时候我们需要声明才可以使用全局变量
function func(){global outervar;}
- 简单的流程控制
for(a = 0;a<10;a++) {break;continue;}
if(a){}
文法
我们先简单写一下文法,因为bison是LALR文法,注意一下和LL系列文法的区别
如果是自己要制作编程语言的话不妨参考一下C语言的bison文法:http://www.quut.com/c/ANSI-C-grammar-y-1998.html
一般情况下,非终结符我们规定都是小写的,终结符都是大写的
先看开头部分
translation_unit: definition_or_statement
| translation_unit definition_or_statement
;
我们认为所有的语句,函数等都会规约成 translation_unit ,多个语句或者是定义可以被规约成一个,
|
是代表或的意思,;
这小段文法的结束
definition_or_statement:function_definition
|statement
;
一般语句和定义可以由语句或者函数定义规约
函数定义我们认为类似于这样的 function funcname(arg1,arg2){}
和下面对应,我们可以定义有参数和无参的函数
function_definition: FUNCTION IDENTIFIER LP arglist RP block
|FUNCTION IDENTIFIER LP RP block
;
语句:
statement:expression_statement
|global_declaration
|for_statement
|if_statement
|break_statement
|continue_statement
|return_statement
;
表达式语句:我们每个语句都是由;
结尾的,SEMICOLON就是分号
expression_statement:expression SEMICOLON
;
表达式 一般就都有值,可以计算的,比如赋值,加减乘除计算等等
LALR 文法一般是运算级高的先规约,一般情况下常量先规约,一般是单目运算符,括号,函数调用先规约
primary_expression:SUB primary_expression /* 取负 */
|LP expression RP /* 括号 */
|IDENTIFIER /* 变量名 */
|STRING_LITERAL /* 字符串 */
|INT_LITERAL /* 整数 */
|DOUBLE_LITERAL /* 浮点 */
|IDENTIFIER LP RP /* 无参数函数调用 */
|IDENTIFIER LP arglist RP
;
下面开始简单的四则运算乘除法会比加减有更高的优先级别,所以primary_expression优先规约成mul_div_expression
mul_div_expression:primary_expression
|mul_div_expression DIV primary_expression
|mul_div_expression MUL primary_expression
;
加减法:
add_sub_expression:mul_div_expression
|add_sub_expression ADD mul_div_expression
|add_sub_expression SUB mul_div_expression
;
同理比较运算和等于不等于运算省略
上面的可以规约为赋值表达式 (ASSIGN 是等于=
在lex文件中定义)
expression: value_expression
|IDENTIFIER ASSIGN expression
表达式可以在上面规约为语句,因此表达式部分的文法就完成了
if语句也很简单
if_statement: IF LP expression RP block
;
for语句:
for_statement: FOR LP expression_option SEMICOLON expression_option SEMICOLON expression_option RP block
;
程序块:
block:LC RC
|LC statement_list RC
;
break,return,continue都一样
break_statement:BREAK SEMICOLON
;
continue_statement:CONTINUE SEMICOLON
;
还有一些没解释的都很容易理解
现在已经定义的全部文法:
translation_unit: definition_or_statement
| translation_unit definition_or_statement
;
definition_or_statement:function_definition
|statement
;
function_definition: FUNCTION IDENTIFIER LP arglist RP block
|
FUNCTION IDENTIFIER LP RP block
;
statement:expression_statement
|global_declaration
|for_statement
|if_statement
|break_statement
|continue_statement
|return_statement
;
expression_statement:expression SEMICOLON
;
expression: value_expression
|IDENTIFIER ASSIGN expression
;
value_expression: compare_expression
|value_expression EQ compare_expression
|value_expression NE compare_expression
;
compare_expression:add_sub_expression
|compare_expression GT add_sub_expression
|compare_expression GE add_sub_expression
|compare_expression LT add_sub_expression
|compare_expression LE add_sub_expression
;
add_sub_expression:mul_div_expression
|add_sub_expression ADD mul_div_expression
|add_sub_expression SUB mul_div_expression
;
mul_div_expression:primary_expression
|mul_div_expression DIV primary_expression
|mul_div_expression MUL primary_expression
;
primary_expression:SUB primary_expression
|LP expression RP
|IDENTIFIER
|STRING_LITERAL
|INT_LITERAL
|DOUBLE_LITERAL
|IDENTIFIER LP RP
|IDENTIFIER LP arglist RP
;
statement_list:statement_list statement
|statement
;
block:LC RC
|LC statement_list RC
;
arglist:arglist COMMA arg
|
arg
;
arg: IDENTIFIER
;
expression_option:
|expression
;
for_statement: FOR LP expression_option SEMICOLON expression_option SEMICOLON expression_option RP block
;
if_statement: IF LP expression RP block
;
break_statement:BREAK SEMICOLON
;
continue_statement:CONTINUE SEMICOLON
;
return_statement:RETURN IDENTIFIER
;
global_declaration:GLOBAL IDENTIFIER
;