本文法是在CMM文法的基础上做了函数调用,逻辑运算以及数组运算,以及struct的定义,类的定义
:
首先说明一下树节点所应该包含的信息,分别包含了:
节点的类型,当前token的所有信息,int值,real值,数组维数,最重要的是孩子节点指针,这里用一个链表表示所有的孩子。你也可以加上行号,以及其他的信息。
入口是start_STMT.从这个根节点下,它的孩子是class定义的节点和struct定义的节点。(^ is null)
START_STMT------->CLASS_STMT | STRUCT_STMT
CLASS_STMT------->class { CLASS_BODY_SEQ }
CLASS_BODY_SEQ------->CLASS_BODY_SEQ CLASS_BODY_STMT | ^
CLASS_BODY_STMT------->FUNC_STMT | DEC_STMT
STRUCT_STMT------->struct { STRUCT_BODY }
STRUCT_BODY------->STRUCT_BODY DEC_STMT | DEC_STMT
FUNC_STMT------->FUNC_TYPE ID ( PARA_STMT_SEQ ) { STMT_SEQ }
FUNC_TYPE------->void | int | real | bool
ID------->[a-zA-Z$_]+(a-zA-Z$_0-9)*
PARA_STMT_SEQ------->PARA_STMT_SEQ [,PARA_DEC] | PARA_DEC
PARA_DEC------->TYPE DIMEN_DESC ID
TYPE------->int | real | bool
DIMEN_DESC------->DIMEN_DESC [] | []
STMT_SEQ------->{ STMT_SEQ_BODY }
STMT_SEQ_BODY------->STMT_SEQ_BODY | STMT
STMT------->DEC_STMT | IF_STMT | WHILE_STMT | READ_STMT | WRITE_STMT | RETURN_STMT | CALL_STMT | ASSIGN_STMT | SELF_STMT
DEC_STMT------->TYPE ID DEC_STMT_SUB;
DEC_STMT_SUB------->[=EXP] | DIMEN_SEQ
DIMEN_SEQ------->DIMEN_SEQ[AEXP] | [AEXP]
IF_STMT------->IF( EXP ) STMT_PART [ELSE STMT_PART];
STMT_PART------->STMT | STMT_SEQ
WHILE_STMT------->WHILE (EXP) STMT_SEQ;
READ_STMT------->READ ID [DIMEN_SEQ];
WRITE_STMT------->WRITE EXP;
RETURN_STMT------->RETURN EXP;
CALL_STMT------->ID ( PARA_CALL_SEQ );
PARA_CALL_SEQ------->PARA_CALL_SEQ [,EXP] | EXP
ASSIGN_STMT------->ID [DIMEN_SEQ] = EXP;
SELF_STMT------->SELFOP ID[DIMEN_SEQ] | ID[DIMEN_SEQ] SELFOP;
SELFOP------->++ | --
EXP------->OR
OR------->AND[|| OR]
AND------->NOT [|| AND]
NOT------->^NOT | EQEXP | CONSTBOOL
EQEXP------->AEXP EOP AEXP
EOP------->< | <= | > | >= | == | !=
AEXP------->TEXP AOP TEXP
AOP------->+ | -
TEXP------->UNAEXP TOP UNAEXP
TOP------->* | / | %
UNAEXP------->[POP] ELEMENT | ELEMENT [SELFOP]
POP------->SELFOP | -
ELEMENT------->CONST | ID2 | ( EXP )
:
首先说明一下树节点所应该包含的信息,分别包含了:
节点的类型,当前token的所有信息,int值,real值,数组维数,最重要的是孩子节点指针,这里用一个链表表示所有的孩子。你也可以加上行号,以及其他的信息。
入口是start_STMT.从这个根节点下,它的孩子是class定义的节点和struct定义的节点。(^ is null)
START_STMT------->CLASS_STMT | STRUCT_STMT
CLASS_STMT------->class { CLASS_BODY_SEQ }
CLASS_BODY_SEQ------->CLASS_BODY_SEQ CLASS_BODY_STMT | ^
CLASS_BODY_STMT------->FUNC_STMT | DEC_STMT
STRUCT_STMT------->struct { STRUCT_BODY }
STRUCT_BODY------->STRUCT_BODY DEC_STMT | DEC_STMT
FUNC_STMT------->FUNC_TYPE ID ( PARA_STMT_SEQ ) { STMT_SEQ }
FUNC_TYPE------->void | int | real | bool
ID------->[a-zA-Z$_]+(a-zA-Z$_0-9)*
PARA_STMT_SEQ------->PARA_STMT_SEQ [,PARA_DEC] | PARA_DEC
PARA_DEC------->TYPE DIMEN_DESC ID
TYPE------->int | real | bool
DIMEN_DESC------->DIMEN_DESC [] | []
STMT_SEQ------->{ STMT_SEQ_BODY }
STMT_SEQ_BODY------->STMT_SEQ_BODY | STMT
STMT------->DEC_STMT | IF_STMT | WHILE_STMT | READ_STMT | WRITE_STMT | RETURN_STMT | CALL_STMT | ASSIGN_STMT | SELF_STMT
DEC_STMT------->TYPE ID DEC_STMT_SUB;
DEC_STMT_SUB------->[=EXP] | DIMEN_SEQ
DIMEN_SEQ------->DIMEN_SEQ[AEXP] | [AEXP]
IF_STMT------->IF( EXP ) STMT_PART [ELSE STMT_PART];
STMT_PART------->STMT | STMT_SEQ
WHILE_STMT------->WHILE (EXP) STMT_SEQ;
READ_STMT------->READ ID [DIMEN_SEQ];
WRITE_STMT------->WRITE EXP;
RETURN_STMT------->RETURN EXP;
CALL_STMT------->ID ( PARA_CALL_SEQ );
PARA_CALL_SEQ------->PARA_CALL_SEQ [,EXP] | EXP
ASSIGN_STMT------->ID [DIMEN_SEQ] = EXP;
SELF_STMT------->SELFOP ID[DIMEN_SEQ] | ID[DIMEN_SEQ] SELFOP;
SELFOP------->++ | --
EXP------->OR
OR------->AND[|| OR]
AND------->NOT [|| AND]
NOT------->^NOT | EQEXP | CONSTBOOL
EQEXP------->AEXP EOP AEXP
EOP------->< | <= | > | >= | == | !=
AEXP------->TEXP AOP TEXP
AOP------->+ | -
TEXP------->UNAEXP TOP UNAEXP
TOP------->* | / | %
UNAEXP------->[POP] ELEMENT | ELEMENT [SELFOP]
POP------->SELFOP | -
ELEMENT------->CONST | ID2 | ( EXP )
ID2------->ID [DIMEN_SEQ] | ID (PARA_CALL_SEQ)
以上便是涉及到的所有文法。实现采用自顶向下分析方法。