Lexical Analysis에서 lexer에게 'regular expression'을 사용해 토큰을 만들어내도록 했던 것처럼, syntax analysis에서도 parser에게 명료한 syntax를 정의해줄 필요가 있다.
그렇다면 syntax analyzer에게 어떻게 올바른 syntax를 전달할 수 있을까?!
int main() {
int 3num = 1234; // c에서 변수이름은 digit으로 시작할 수 없는데 3으로 시작하므로, lexical error
return 0;
}
int main() {
/* comment // 주석이 /\* 로 시작하지만 \*/로 끝나지 않으므로, 주석 패턴에 맞지 않아서 lexical error 발생
cout << 'GFG!';
return 0;
}
INT_KEYWORD = int
ID = [a-z]
ASSIGNMENT = '='
NUM = [0-9]int a = 9
double a = 1
이 경우엔 lexical error X
INT_KEYWORD = int
ID = [a]
ASSIGNMENT = '='
NUM = [0-9]int a = 9
double a = 1
이 경우엔 Lexer가 'double'을 알지 못함 => lexical error 발생 !
PROGRAM = STATEMENT/*
C, 자바 등 program은 zero or more statement이다.STATEMENT = EXPRESSION | IF_STMT | WHILE_STMT | ...
Statement는 expression, if문, while문 등으로 구성된다.OP = + | - | /
EXPRESSSION = (NUM | ID | DECIMAL) OP (NUM | ID | DECIMAL)
✔️ 5 + 10 Valid
✔️ 1 + 2 + 3 Valid
✔️ foo - bar
NUM = RE~
DOT = RE~
ID = RE, '(', ')'~
PLUS = RE~ID DOT ID
obj.var;
obj.foo();Lexical Analysis 에서는 ID DOT ID 패턴을 갖추었기 때문에 옳다. 그렇지만 자바에서, 해당 내용은 Syntax Analysis에서 옳을까?
상황에 따라서 옳을 수도 있고, 아닐 수도 있다.
obj가 위에 먼저 정의되어 있고 var 변수가 obj 안에 있다면 valid하지만 그렇지 않다면 옳지 않다.
이러한 것을 Syntaxl analyzer가 점검한다.
import xxx;
obj.var;
obj.foo;
int main() {
..
}
이 코드라면, lexer는 obj.var;을 ID DOT ID 토큰으로 생성하고 complain 하지 않겠지만 Syntax analyzer는 complain하고 error을 발생시킨다.
▪️ 예시
Program = statement*
statement = NUM PLUS NUM;
2+2, 1+1, 5+5;
(5+5) 는 어떻게 표현할 수 있을까?
LP.RP = ()
((5)+5) 와 같은 (())은 어떻게 Regular Expression으로 표현할 수 있을까?
(LP.RP)+ = ()()()() != (()) => 즉 불가능하다!
Lexical Analysis : Regular Expression을 사용하여 source code => Tokens
Syntax Anlaysis : Context Free Grammer을 사용하여 Tokens => AST