Tên chính xác cho một trình phân tích cú pháp gốc đệ quy sử dụng các vòng lặp để xử lý đệ quy trái?


8

Ngữ pháp này được để lại đệ quy:

Expression  ::= AdditionExpression

AdditionExpression  ::=
    MultiplicationExpression
        | AdditionExpression '+' MultiplicationExpression
        | AdditionExpression '-' MultiplicationExpression

MultiplicationExpression    ::=
    Term
        | MultiplicationExpression '*' Term
        | MultiplicationExpression '/' Term

Term    ::=
    Number
        | '(' AdditionExpression ')'

Number  ::=
    [+-]?[0-9]+(\.[0-9]+)?

Vì vậy, trên lý thuyết, dòng dõi đệ quy sẽ không hoạt động. Nhưng bằng cách khai thác các thuộc tính của ngữ pháp mà mỗi quy tắc đệ quy trái tương ứng với một mức độ ưu tiên cụ thể và giao diện của một mã thông báo duy nhất là đủ để chọn sản xuất chính xác, các quy tắc đệ quy trái có thể được phân tách riêng lẻ trong khi các vòng lặp.

Ví dụ, để phân tích cú pháp không đầu cuối AdditionExpression, mã giả này đủ:

function parse_addition_expression() {
    num = parse_multiplication_expression()
    while (has_token()) {
        get_token()
        if (current_token == PLUS)
            num += parse_multiplication_expression()
        else if (current_token == MINUS)
            num -= parse_multiplication_expression()
        else {
            unget_token()
            return num
        }
    }
    return num
}

Tên chính xác cho loại trình phân tích cú pháp này là gì? Bài viết thông tin này chỉ đề cập đến nó như là "Giải pháp cổ điển": https://www.engr.mun.ca/~theo/Misc/Ex_parsing.htmlm

Phải có một tên thích hợp cho loại trình phân tích cú pháp này.


Đối với tôi nó không phải là một loại trình phân tích cú pháp, nó chỉ là ứng dụng loại bỏ đệ quy trái kết hợp với trình phân tích cú pháp gốc đệ quy. Xem câu hỏi này cho một kỹ thuật để loại bỏ đệ quy trái.
AProgrammer

Tôi nghĩ bạn có thể đúng. Nó không giống với thời gian chạy của thuật toán loại bỏ đệ quy trái.
dùng71015

1
Vui lòng không sử dụng hộp 'câu trả lời' để đăng bình luận hoặc nhận xét khác. Nếu bạn tạo một tài khoản , bạn sẽ giữ quyền truy cập và có thể chấp nhận câu trả lời giúp bạn nhiều nhất. Nếu bạn đã nhập email và mất quyền truy cập, bạn có thể khôi phục quyền truy cập . Nếu bạn không nhập địa chỉ email và không có quyền truy cập vào trình duyệt / cookie bạn đã sử dụng để đăng câu hỏi, có lẽ bạn đã hết may mắn. Không ai khác có thể chấp nhận câu trả lời cho bạn - thậm chí không phải người điều hành.
DW

Câu trả lời:


11

Nó chỉ là một trình phân tích cú pháp LL (1) được thực hiện với gốc đệ quy.

Bắt đầu với:

AdditionExpression  ::=
    MultiplicationExpression
        | AdditionExpression '+' MultiplicationExpression
        | AdditionExpression '-' MultiplicationExpression

áp dụng loại bỏ đệ quy trái để có ngữ pháp LL (1):

AdditionExpression  ::= 
    MultiplicationExpression AdditionExpressionTail

AdditionExpressionTail ::=
        | '+' MultiplicationExpression AdditionExpressionTail
        | '-' MultiplicationExpression AdditionExpressionTail

viết các hàm tương ứng:

function parse_AdditionExpression() {
    parse_MultiplicationExpression()
    parse_AdditionExpressionTail()
}

function parse_AdditionExpressionTail() {
    if (has_token()) {
        get_token()
        if (current_token == PLUS) {
            parse_MultiplicationExpression()
            parse_AdditionExpressionTail()
        } else if (current_token == MINUS) {
            parse_MultiplicationExpression()
            parse_AdditionExpressionTail()
        } else {
            unget_token()
        }
    }
}

xóa đệ quy đuôi:

function parse_AdditionExpressionTail() {
    while (has_token()) {
        get_token()
        if (current_token == PLUS)
            parse_MultiplicationExpression()
        else if (current_token == MINUS)
            parse_MultiplicationExpression()
        else {
            unget_token()
            return
        }
    }
}

nội tuyến:

function parse_AdditionExpression() {
    parse_MultiplicationExpression()
    while (has_token()) {
        get_token()
        if (current_token == PLUS)
            parse_MultiplicationExpression()
        else if (current_token == MINUS)
            parse_MultiplicationExpression()
        else {
            unget_token()
            return
        }
    }
}

và bạn chỉ cần thêm xử lý ngữ nghĩa để có được chức năng của bạn.


6

kk biểu tượng .

*

Xem ở đây để biết tổng quan toàn diện về mức độ mạnh mẽ của lớp trình phân tích cú pháp này.


1
Tôi không thấy điều này có liên quan. Mã không sử dụng nhiều hơn một biểu tượng nhìn về phía trước.
AProgrammer

@AProgrammer Vì vậy, nó là trình phân tích cú pháp LL (1) hoặc liên quan rất chặt chẽ.
Raphael

Đó là một trình phân tích cú pháp LL (1). Tôi mở rộng nhận xét của mình thành một câu trả lời.
AProgrammer

2
@AProgrammer Tôi không thấy câu trả lời thứ hai là cần thiết. LL (1) là LL (k) cho k = 1 (không rõ ràng phải không?). Nhưng tốt
Raphael
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.