우분투 flex에서 regular expression 질문이 있습니다!
글쓴이: skyinyour / 작성시간: 금, 2016/04/01 - 12:39오전
안녕하세요 ! flex로 입력 코드를(파일로 읽습니다!) 변수인지 키워드인지 등등 나눠볼까 합니다!
문제가 되는게..
int val = 13;
int val= 13;
이 두 가지 케이스를 모두 고려한 regular expression 을 짜보려고 하는데 뭔가 핵심적인 부분을 모르고 있다는 생각이 드네요 ㅠㅠ
제가 val 이나 int 에 관한 regex 를 [a-zA-Z]|[a-zA-Z]+ 로 잡아 놓으면 첫 번째 케이스에서는 인식을 하는데 두 번째 케이스에서는 인식을 못하더라구요.
yytext가 val= 까지 읽어서 문제라 생각하고 케이스를 나누었는데.. 문제는 =에 대한 regex, 숫자.. 등 regex가 늘어날수록 하나가 되면 하나가 안되고 꼬리에 꼬리를물고 해결이 되지 않네요 ㅠㅠ
보통 이런식으로 token들을 나눌때 고려해야하는 사항이나 올바른 프로세스? 에 대해서 조언좀 부탁드립니다 ㅠㅠ
Forums:
...
뭔가 코드가 엉뚱한 데서 잘못된 것 같은데요. regex가 [a-zA-Z]|[a-zA-Z]+로 되어 있으면 뒤에 "="가 오든 공백이 오든 그걸 포함할 이유가 없죠.
동일한 문제가 발생하는 코드를 20줄 이내로 줄여서 보여주세요. (줄이는 과정 중에 문제를 발견할 확률 90%)
* 그리고 문제의 regex는 그냥 [a-zA-Z]+로 쓰는 것과 똑같지 않나요?
\b.*[\s].*[\=].*[;] 요구 조건은 잘
요구 조건은 잘 모르겠지만 일단 정규식 하나 던져봅니다.
소곤소곤
어디서 문제가나는지 알겠지만 어렵네요 ㅠㅠ
저는 우선 키워드나 변수에 대해서
letter [a-zA-Z]|[a-zA-Z]+|[a-zA-Z]+"."[a-zA-Z]+ 로 하였습니다.
. 은 serial.begin 이런거 때문에 들어간거구요
문제가 발생했던게 처음에 int i = 3; 여기서 [a-zA-Z] 이부분이 한 개의 캐릭터를 인식못하더라구요
그래서 " "?[a-zA-Z]" "? 를 붙이면서 문제는 늪?으로 빠져들어버렸습니다 ㅠㅠ. i는 인식하지만
int i = 3; 여기서 = 이 충돌? 이 일어나는것 같아요.
=을 위해서 assignment " "?[=]+ 라고 해놓았더니.. 둘중 하나가 되면 하나는 안되는 아주 동전의 양면같은 현상이...ㅠㅠ
더군다나 숫자를
digit [0-9]|[0-9]+ 로 해놓았는데 여기서 숫자 3 또한 그냥 이 상태로는 검출이 안됩니다.. 그래서 앞에 " "를 붙이고 하다보니 저 3개가 아주그냥.. 3개중 2개는 되고 1개는 안되는 현상이..
여기서 꼬여버린것같아요..
우선 무엇보다도letter의 첫 번째 규칙이 [a-zA-Z] 에서 왜 single character가 검출이 안되는지 도무지 이해를 못하겠네요 ㅠㅠ
flex에 대해 얼마나 이해하고 계신지?
단편적인 정보만으로는 도저히 무슨 일이 일어나고 있는지 파악할 수 없군요.
특히 질문글로부터 질문자님이 flex 및 소스 언어에 대한 명세를 제대로 이해하고 있지 않다는 느낌이 강하게 듭니다. 제 착각이라면 사과드리겠습니다만.
일단 지금 상황에서 몇 가지만 우선 지적드리죠. 소스 언어는 C언어인 것으로 보이는데 맞나요?
1. C언어 identifier에 대응하는 정규식은 [_a-zA-Z][_a-zA-Z0-9]*입니다.
2. 10진 숫자는 0|[1-9][0-9]*이고요. 한편 8진법(0으로 시작) 및 16진법(0x 혹은 0X으로 시작) 숫자도 고려를 해 줘야 됩니다.
3. 공백 문자, 혹은 연속된 공백 문자들은 한번에 인식해서(뭐 대충 [ \t\n]+ 이런 식으로) 무시해 버리는 게 효과적입니다. 일종의 토큰 구분자 역할이죠.
4. serial.begin 같은 걸 잡겠다고 "." 양쪽의 두 identifier까지 포괄하는 정규표현식을 만드는 건 별로 바람직하지 못한 생각입니다. 별 희한한 조합이 다 나올 수 있기 때문이죠. a.b.c 같은 건 물론이고, a.b[i].c 같은 것도 가능합니다. 이런 건 bison 등의 parser generator에 맡겨야 합니다.
5. 컴파일러 프론트엔드처럼 소스 언어를 전부 파싱할 필요까지는 없다지만, 질문자님의 의도를 flex만으로 이루는 건 거의 불가능해 보이는군요. 사실 정말 제대로 하려면 전처리기 구현부터 시작해서 상당한 노력이 필요할 것 같습니다만.
flex를 처음 접하고 말씀하신대로 제대로 이해하지못하고있습니다..ㅠㅠ
제가 결국 하고자 하는것은 source code를 input file로 하여 keyword 나 digit , special symbol 등을 구분하여 print 해주는 것입니다.
길이상 파일로 첨부하였습니다 ㅠㅠ
공백을 [ \t\n]+ {;} 이런식으로 처리하였는데도... 토큰이 구분이 가질 않네요 ㅠㅠ 첨부파일 한번 봐주시고 이 문제에 대해서 그리고 컴파일러를 공부중에 해보는건데 책이나 공부방향에 대해서(너무 광범위한 질문이지만... 너무 방향을못잡고있어서 제가ㅠ) 조언 부탁드립니다.. !
...
lexer는 문장을 한번에 통째로 인식하려고 쓰는 도구가 아닙니다. 하나씩 잘라서 토큰에 넣도록 짜보세요.
예를 들면 "int val = 13;"이라면 flex가 "int" (예약어), "val" (ID), "=" (연산자), "13" (숫자), ";" (세미콜론...) 이렇게 다섯 개의 토큰을 돌려주도록 만드는 겁니다.
그러면 문제가 생겼을 때 어느 부분에서 문제가 생겼는지 쉽게 알 수 있습니다.
댓글 달기