date: 2024-11-20
title: Compiler Project Language Features
status: DONE
author:
- AllenYGY
tags:
- Compiler
- Project
- Document
description: Compiler Project Set Algebra Calculator Language Features
publish: True
Compiler Project Language Features
Basic data type
Range between 0-4199999999
A single-digit integer is an arbitrary decimal number.
A multi-digit integer starts with a non-zero decimal number and followed by any sequence of arbitrary decimal numbers.
Users can only declare non-negative integers. Negative integers are constructed through subtraction operations.
Constructed data type
Users are not allowed to declare an arithmetic expression. There is no specific data type keyword for arithmetic expressions in the language. This data type only exists in the compiler. You can also check the keywords. There is no data type keyword for arithmetic expressions.
An atomic arithmetic expression is either an integer constant or an integer variable.
A compound arithmetic expression consists of two arithmetic expressions connected by an arithmetic operator (addition "+", subtraction "-", multiplication "*" ).
And parentheses are used to define substructures within expression. For example,
is parsed as:
Constructed data type
Same as arithmetic expression, predicates are not directly declared by users but are instead managed within the compiler.
An atomic predicate is a relational comparison, which can be of two types:
A compound predicate is formed by combining “smaller” predicates (either atomic or compound) using logical operators:
Binary logical operators: two (atomic or compound) predicates connected by a conjunction (“&”) or disjunction (“|”)
Unary logical operators: Negation (“!”) which precedes another predicate.
For example,
and
where P, Q, and R are predicates.
Parentheses are also used to define substructures in predicates. Parentheses are essential for defining the precedence and grouping of operations within predicates, ensuring the correct evaluation of complex expressions.
let be show int set+-*@<>&|!UI
def parse(self):
self.stack.append(0) # 初始状态
current_token = self.tokens[self.index] if self.index < len(self.tokens) else None
while True:
state = self.stack[-1] # 获取当前状态
action, value = self.actions.get((state, current_token.token_type if current_token else "$"), (None, None))
if action is None:
print(f"Syntax Error: Unexpected token '{current_token.lexeme if current_token else 'EOF'}'")
return
if action == "s": # 移入操作
self.stack.append(value) # 将目标状态压入栈
self.index += 1 # 移动到下一个 token
current_token = self.tokens[self.index] if self.index < len(self.tokens) else None
elif action == "r": # 规约操作
lhs, rhs_length = self.rules[value] # 获取产生式左部和右部长度
print("lhs,rhs_length",lhs,rhs_length)
for _ in range(rhs_length): # 弹出 RHS 长度的符号
self.stack.pop()
state = self.stack[-1] # 获取规约后的栈顶状态
print(state,lhs)
self.stack.append(self.goto[(state, lhs)]) # 根据 GOTO 表转移
elif action == "acc": # 接受状态
print("Syntactic Analysis Complete!")
return