2014-06-19 22 views
5

Tôi đã sử dụng phiên bản ANTLR 4 để tạo trình biên dịch. Giai đoạn đầu tiên là phần Lexer. Tôi tạo ra "CompilerLexer.g4" tập tin và quy tắc lexer putted trong it.It hoạt động tốt.Sử dụng trình phân tích cú pháp ANTLR và Lexer tách biệt

CompilerLexer.g4:


lexer grammar CompilerLexer; 

INT   : 'int' ; //1 
FLOAT  : 'float' ; //2 
BEGIN  : 'begin' ; //3 
END   : 'end' ; //4 
To   : 'to' ; //5 
NEXT  : 'next' ; //6 
REAL  : 'real' ; //7 
BOOLEAN  : 'bool' ; //8 
. 
. 
. 
NOTEQUAL : '!=' ; //46 
AND   : '&&' ; //47 
OR   : '||' ; //48 
POW   : '^'  ; //49 
ID   : [a-zA-Z]+ ; //50 




WS 
: ' ' -> channel(HIDDEN) //50 
; 

Bây giờ đó là thời gian cho giai đoạn 2 là parser.I tạo "CompilerParser.g4" tập tin và putted văn phạm trong đó nhưng có hàng chục cảnh báo và lỗi.

CompilerParser.g4:


parser grammar CompilerParser; 

options { tokenVocab = CompilerLexer; } 

STATEMENT : EXPRESSION SEMIC 
     | IFSTMT 
     | WHILESTMT 
     | FORSTMT 
     | READSTMT SEMIC 
     | WRITESTMT SEMIC 
     | VARDEF SEMIC 
     | BLOCK 
     ; 

BLOCK  : BEGIN STATEMENTS END 
     ; 

STATEMENTS : STATEMENT STATEMENTS* 
     ; 

EXPRESSION : ID ASSIGN EXPRESSION 
     | BOOLEXP 
     ; 

RELEXP  : MODEXP (GT | LT | EQUAL | NOTEQUAL | LE | GE | AND | OR) RELEXP 
     | MODEXP 
     ; 

. 
. 
. 

VARDEF  : (ID COMA)* ID COLON VARTYPE 
     ; 

VARTYPE  : INT 
     | FLOAT 
     | CHAR 
     | STRING 
     ; 
compileUnit 
: EOF 
; 

Cảnh báo và các lỗi:

  • định nghĩa tiềm ẩn của token 'BLOCK' trong phân tích cú pháp
  • định nghĩa tiềm ẩn của token ' BOOLEXP 'trong trình phân tích cú pháp
  • định nghĩa tiềm ẩn của token 'EXP' trong phân tích cú pháp
  • định nghĩa tiềm ẩn của token 'EXPLIST' trong phân tích cú pháp
  • lexer quy tắc 'BLOCK' không được phép vào phân tích cú pháp
  • lexer quy tắc 'EXP' không được phép vào phân tích cú pháp
  • quy tắc
  • lexer 'EXPLIST' không được phép vào phân tích cú pháp
  • lexer quy tắc 'EXPRESSION' không được phép vào phân tích cú pháp

Có hàng chục các cảnh báo và lỗi. Nguyên nhân là gì?

Câu hỏi chung: Sự khác biệt giữa việc sử dụng ngữ pháp kết hợp và sử dụng lexer và phân tích cú pháp riêng biệt là gì? Làm thế nào nên tham gia các tập tin ngữ pháp và lexer riêng biệt?

Trả lời

7

Quy tắc Lexer bắt đầu bằng chữ in hoa và quy tắc phân tích cú pháp bắt đầu bằng chữ thường. Trong ngữ pháp phân tích cú pháp, bạn không thể xác định mã thông báo. Và vì ANTLR nghĩ rằng tất cả các quy tắc lexer quy tắc cao hơn của bạn, nó tạo ra các lỗi/cảnh báo.

EDIT

user2998131 đã viết:

Câu hỏi chung: sự khác biệt giữa việc sử dụng kết hợp ngữ pháp và sử dụng lexer và phân tích cú pháp riêng là gì?

Tách các quy tắc lexer và phân tích cú pháp sẽ giữ mọi thứ được sắp xếp. Ngoài ra, khi tạo các ngữ pháp lexer và phân tích cú pháp riêng biệt, bạn không thể (vô tình) đặt các mã thông báo bên trong ngữ pháp phân tích cú pháp của bạn nhưng sẽ cần xác định tất cả các thẻ trong ngữ pháp lexer của bạn.Điều này sẽ làm cho nó rõ ràng các quy tắc lexer nhận phù hợp trước khi những người khác, và bạn không thể thực hiện trong kỳ thẻ đen bất kỳ của typo:

grammar P; 

r1 : 'foo' r2; 

r2 : r3 'foo '; // added an accidental space after 'foo' 

Nhưng khi bạn có một ngữ pháp phân tích cú pháp, bạn không thể làm cho sai lầm đó. Bạn sẽ phải sử dụng quy tắc lexer phù hợp 'foo':

parser grammar P 

options { tokenVocab=L; } 

r1 : FOO r2; 

r2 : r3 FOO; 


lexer grammar L; 

FOO : 'foo'; 

user2998131 đã viết:

Làm thế nào nên tham gia tập ngữ pháp và lexer riêng biệt?

Cũng giống như bạn làm trong ngữ pháp phân tích cú pháp của bạn: bạn trỏ đến đúng tokenVocab bên trong khối options { ... }.

Lưu ý rằng bạn cũng có thể nhập khẩu ngữ pháp, có điều gì đó khác: https://theantlrguy.atlassian.net/wiki/display/ANTLR4/Grammar+Structure#GrammarStructure-GrammarImports

+0

Vấn đề chính được giải quyết. Làm thế nào về câu hỏi chung? – user2998131

+0

@ user2998131, ah, đã bỏ qua chúng. Sẽ trả lời những người đó sau. –

+0

@ user2998131, kiểm tra ** EDIT ** của tôi. –

Các vấn đề liên quan