cuốn sách gpt4 ai đã làm

Java - Phân tích toán tử bậc ba bằng thuật toán shunting yard

In lại Tác giả: Taklimakan Thời gian cập nhật: 2023-11-02 19:15:30 27 4
mua khóa gpt4 Nike

Đối với bối cảnh, đọc câu hỏi này về Toán tử bậc baĐầu tiên.

Tôi đang xây dựng ngôn ngữ lập trình của riêng mình để cho phép bạn xác định các toán tử tùy chỉnh. Vì tôi muốn nó có càng ít trình biên dịch tích hợp càng tốt, nên nó sẽ cho phép định nghĩa tùy chỉnh của toán tử bậc ba, tốt nhất là ở dạng sau

toán tử trung tố ? : { độ ưu tiên 120 }

Trình phân tích cú pháp biểu thức (viết tay) của tôi chuyển đổi các toán tử ba ngôi lồng nhau thành một danh sách các toán hạng được phân tách bằng các toán tử.

một ?b ?
(a) ? (b) ? (c) : (d) : (d)
OperatorChain(các toán tử: [?, ?, :, :], toán hạng: [a, b, c, d, e])

Toán tửChuỗi Bây giờ, lớp này tìm kiếm một toán tử từ định nghĩa toán tử trong phạm vi và chuyển đổi danh sách thành nút AST nhị phân bằng cách sử dụng phiên bản sửa đổi của thuật toán shunting yard như sau:

// Lưu ý: OperatorElement là một lớp chỉ lưu trữ Mã định danh, vị trí mã nguồn liên quan và toán tử được giải quyết.
// IValue là giao diện cơ sở cho tất cả các nút AST biểu thức

Stack cuối cùng operatorStack = new LinkedList<>();
Stack cuối cùng operandStack = new LinkedList<>();
operandStack.push(this.operands[0]);

for (int i = 0; i < this.operatorCount; i++)
{
phần tử OperatorElement cuối cùng1 = this.operators[i];
Phần tử toán tử2;
trong khi (!operatorStack.isEmpty())
{
element2 = operatorStack.peek();

int cuối cùng so sánhPrecedence = element1.operator.comparePrecedence(element2.operator);
if (so sánhƯu tiên < 0
|| element1.operator.getAssociativity() != IOperator.RIGHT && so sánhPrecedence == 0)
{
operatorStack.pop();
this.pushCall(operandStack, element2);
}
khác
{
phá vỡ;
}
}
operatorStack.push(element1);
operandStack.push(this.operands[i + 1]);
}
trong khi (!operatorStack.isEmpty())
{
this.pushCall(operandStack, operatorStack.pop());
}

return operandStack.pop().resolve(markers, context);

Làm cách nào để sửa đổi thuật toán này để sử dụng toán tử ba ngôi, bao gồm cả toán tử tùy chỉnh?

câu trả lời hay nhất

Tôi đã triển khai một trình phân tích cú pháp toán học trong Java có thể xử lý toán tử bậc ba. Cốt lõi của nó là sự biểu lộ phương pháp. Đầu vào được chứa trong iterator trong, sử dụng it.peekNext() phương pháp để xem mã thông báo tiếp theo và sau đó it.consum() Di chuyển đến mã thông báo tiếp theo. nó gọi tiền tốSuffix() để đọc các hằng số và biến bằng cách sử dụng các toán tử tiền tố và hậu tố có thể có, ví dụ: ++x.

biểu thức void được bảo vệ () ném ParseException {

tiền tốSuffix();

Mã thông báo t = it.peekNext();
while(t!=null) {
if(t.isBinary()) {
OperatorToken ot = (OperatorToken)t;
Toán tử op = ot.getBinaryOp();
pushOp(op,ot);
it.consume();
tiền tốSuffix();
}
khác nếu(t.isTernary()){
OperatorToken ot =(OperatorToken)t;
Toán tử = ot.getTernaryOp();
pushOp(đến,ot);
it.consume();
tiền tốSuffix();
}
khác
phá vỡ;
t=it.peekNext();
}
// đọc tất cả phần tử còn lại trong ngăn xếp
while(!sentinel.equals(ops.peek())) {
popOp();
}
}

Vì vậy, khi gặp một trong những điểm đánh dấu này, nó sẽ gọi đẩyOp phương thức đẩy chúng vào ngăn xếp. Mỗi mã thông báo có một toán tử liên quan, toán tử này cũng được phân tích cú pháp thành đẩyOp.

pushOp so sánh toán tử mới với đầu ngăn xếp và bật nó lên nếu cần

protected void pushOp(Operator op,Token tok) ném ParseException 
{
while(so sánhOps(ops.peek(),op))
popOp();
ops.push(op);
}

Logic để xử lý toán tử bậc ba xảy ra trongso sánhOps中:

/**
* So sánh các toán tử dựa trên mức độ ưu tiên và tính kết hợp của chúng.
* @param op1
* @param op2
* @return true nếu op1 có mức độ ưu tiên thấp hơn op2 hoặc mức độ ưu tiên bằng và một trợ lý bên trái, v.v.
*/
so sánh boolean được bảo vệ(Toán tử op1,Toán tử op2)
{
if(op1.isTernary() && op2.isTernary()) {
if(op1 instanceof TernaryOperator.RhsTernaryOperator &&
op2 instanceof TernaryOperator.RhsTernaryOperator )
trả về đúng sự thật;
trả về sai;
}
if(op1 == canh gác ) trả về sai;
if(op2 == canh gác ) trả về true;
if(op2.isPrefix() && op1.isBinary()) trả về sai;
if(op1.getPrecedence() < op2.getPrecedence()) trả về true;
if(op1.getPrecedence() == op2.getPrecedence() && op1.isLeftBinding()) trả về true;
trả về sai;
}

Nếu cả hai toán tử đều ở bên phải của toán tử ba ngôi thì so sánhOps Trả về true một toán tử sẽ được bật lên. Ngược lại, nếu cả hai đều là toán tử ba ngôi thuận tay trái, hoặc một là toán tử ba ngôi thuận tay trái và một là toán tử ba ngôi thuận tay phải, thì so sánhOps Trả về sai và không có toán tử nào bật lên.

Một chút xử lý khác xảy ra trong popOp Trong phương pháp:

protected void popOp() ném ParseException
{
Toán tử op = ops.pop();

if(op == ẩnMul) {
Nút rhs = nút.pop();
Nút lhs = nút.pop();
Nút nút = nf.buildOperatorNode(
jep.getOperatorTable().getMultiply(),
lhs, rhs);
nút.push(nút);
}
khác nếu(op.isBinary()) {
Nút rhs = nút.pop();
Nút lhs = nút.pop();
Nút nút = nf.buildOperatorNode(op, lhs, rhs);
nút.push(nút);
}
khác nếu(op.isUnary()) {
Nút lhs = nút.pop();
Nút nút = nf.buildOperatorNode(op, lhs);
nút.push(nút);
}
else if(op.isTernary() && op instanceof TernaryOperator.RhsTernaryOperator ) {
Toán tử op2 = ops.pop();
if(!(op2 instanceof TernaryOperator ) || !((TernaryOperator) op2).getRhsOperator().equals(op)) {
ném ngoại lệ ParseException mới(
MessageFormat.format(JepMessages.getString("configurableparser.ShuntingYard.NextOperatorShouldHaveBeenMatchingTernaryOp"),op2.getName())); //$NON-NLS-1$

}

Nút rhs = nút.pop();
Nút giữa = node.pop();
Nút lhs = nút.pop();
Nút nút = nf.buildOperatorNode(op2, new Node[]{lhs,middle,rhs});
nút.push(nút);
}
khác {
ném ParseException mới(MessageFormat.format(JepMessages.getString("configurableparser.ShuntingYard.InvalidOperatorOnStack"),op.getSymbol())); //$NON-NLS-1$
}
}

Chỉ nên gặp phía bên phải của toán tử ternary. Toán tử ngay bên dưới nó phải là toán tử bên trái tương ứng. (Bất kỳ toán tử nào có mức ưu tiên thấp hơn sẽ được bật lên, toán tử duy nhất có mức ưu tiên cao hơn là toán tử gán, không thể xuất hiện trong toán tử ba ngôi).

Bây giờ các toán tử tay trái và tay phải bật lên. Tôi đang xây dựng một cây và ba nút cuối cùng được tạo sẽ bị xóa và nút toán tử bậc ba mới được tạo.

Về việc phân tích cú pháp toán tử java - ternary bằng thuật toán shunting yard, chúng tôi đã tìm thấy một câu hỏi tương tự trên Stack Overflow: https://stackoverflow.com/questions/36332016/

27 4 0
Chứng chỉ ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com
Xem sitemap của VNExpress