<program> -> <statements> <statements> -> <statement> | <statement> <statements> <statement> -> <declaration> | <assignment> | <print> | <function-definition> | <conditional> | <loop> | <break> | <continue> | <return> <print> -> "print" <expression> ";" <expression> -> <factor> | <factor> "+" <expression> | <factor> "-" <expression> | <factor> "*" <expression> | <factor> "/" <expression> | <factor> "==" <expression> | <factor> "!=" <expression> | <factor> "<" <expression> | <factor> ">" <expression> | <factor> "<=" <expression> | <factor> ">=" <expression> | <factor> "&" <expression> | <factor> "|" <expression> | <factor> "!" <expression> <factor> -> <arrayitem> | <identifier> | <number> | "(" <expression> ")" | <function-call> <arrayitem> -> <identifier> "[" <expression> "]" <number> -> TokenType.NUMBER <identifier> -> TokenType.IDENTIFIER <declaration> -> "int" <identifier> ";" | "int" <identifier> "=" <expression> ";" <assignment> -> <identifier> "=" <expression> ";" <parameters> -> <parameter> | <parameter> "," <parameters> <parameter> -> "int" <identifier> <function-definition> -> "int" <identifier> "(" ")" "{" <statements> "}" | "int" <identifier> "(" <parameters> ")" "{" <statements> "}" <arguments> -> <argument> | <arguments> "," <argument> <argument> -> <expression> <function-call> -> <identifier> "(" ")" | <identifier> "(" <arguments> ")" <conditional> -> "if" "(" <expression> ")" "{" <statements> "}" | "if" "(" <expression> ")" "{" <statements> "}" "else" "{" <statements> "}" <loop> -> "while" "(" <expression> ")" "{" <statements> "}" <break> -> "break" ";" <continue> -> "continue" ";" <return> -> "return" ";" | "return" <expression> ";"
int mod(int a, int b) {
int c = a / b * b;
return a - c;
}
int main() {
int a = 2211247;
int b = 0;
while (a > 0) {
b = b * 10;
b = b + mod(a, 10);
a = a / 10;
}
print b;
return 0;
}
PROGRAM: {
STATEMENTS: {
FUNCTION_DEFIENITION: {
IDENTIFIER: 'mod',
PARAMETERS: {
PARAMETER: {
IDENTIFIER: 'a'
},
PARAMETER: {
IDENTIFIER: 'b'
}
},
STATEMENTS: {
DECLARATION: {
IDENTIFIER: 'c',
EXPRESSION: {
IDENTIFIER: 'a',
OPRATORS: '/',
IDENTIFIER: 'b',
OPRATORS: '*',
IDENTIFIER: 'b'
}
},
RETURN: {
EXPRESSION: {
IDENTIFIER: 'a',
OPRATORS: '-',
IDENTIFIER: 'c'
}
}
}
},
FUNCTION_DEFIENITION: {
IDENTIFIER: 'main',
PARAMETERS: {},
STATEMENTS: {
DECLARATION: {
IDENTIFIER: 'a',
EXPRESSION: {
NUMBER: '2211247'
}
},
DECLARATION: {
IDENTIFIER: 'b',
EXPRESSION: {
NUMBER: '0'
}
},
LOOP: {
EXPRESSION: {
IDENTIFIER: 'a',
OPRATORS: '>',
NUMBER: '0'
},
STATEMENTS: {
ASSIGNMENT: {
IDENTIFIER: 'b',
EXPRESSION: {
IDENTIFIER: 'b',
OPRATORS: '*',
NUMBER: '10'
}
},
ASSIGNMENT: {
IDENTIFIER: 'b',
EXPRESSION: {
IDENTIFIER: 'b',
OPRATORS: '+',
FUNCTION_CALL: {
IDENTIFIER: 'mod',
ARGUMENTS: {
ARGUMENT: {
EXPRESSION: {
IDENTIFIER: 'a'
}
},
ARGUMENT: {
EXPRESSION: {
NUMBER: '10'
}
}
}
}
}
},
ASSIGNMENT: {
IDENTIFIER: 'a',
EXPRESSION: {
IDENTIFIER: 'a',
OPRATORS: '/',
NUMBER: '10'
}
}
}
},
PRINT: {
EXPRESSION: {
IDENTIFIER: 'b'
}
},
RETURN: {
EXPRESSION: {
NUMBER: '0'
}
}
}
}
}
}
class Node:
def __init__(self, type_ : NodeType, value = None):
self.type_ = type_
assert type(value) is str or type(value) is Node or type(value) is NodeList or value is None
self.value = (NodeList(value) if type(value) is str or type(value) is Node else value) if value is not None else NodeList()
def __repr__(self) -> str:
if (self.type_ == NodeType.NUMBER or
self.type_ == NodeType.IDENTIFIER or
self.type_ == NodeType.ARRAYSIZE or
self.type_ == NodeType.OPRATORS):
return f"{self.type_.name}: '{str(self.value)}'"
return f"{self.type_.name}: {{{str(self.value)}}}"
辅助类 NodeList 定义:class NodeList(list):
def __init__(self, *args):
super().__init__(args)
def __repr__(self) -> str:
return ','.join(str(x) for x in self)
Node 类型:class NodeType(Enum):
PROGRAM = 1
STATEMENTS = 2
STATEMENT = 3
DECLARATION = 4
ASSIGNMENT = 5
FUNCTION_CALL = 6
FUNCTION_DEFIENITION = 7
CONDITIONAL = 8
LOOP = 9
BREAK = 10
CONTINUE = 11
RETURN = 12
EXPRESSION = 13
NOCOMPARE = 14
TERM = 15
FACTOR = 16
ARRAYITEM = 17
IDENTIFIER = 18
NUMBER = 19
PARAMETERS = 20
PARAMETER = 21
ARGUMENTS = 22
ARGUMENT = 23
OPRATORS = 24
PRINT = 25
ARRAYSIZE = 26 # actually a number, but only used for array size so it's a separate type