우분투 flex에서 regular expression 질문이 있습니다!

skyinyour의 이미지

안녕하세요 ! flex로 입력 코드를(파일로 읽습니다!) 변수인지 키워드인지 등등 나눠볼까 합니다!

문제가 되는게..

int val = 13;

int val= 13;

이 두 가지 케이스를 모두 고려한 regular expression 을 짜보려고 하는데 뭔가 핵심적인 부분을 모르고 있다는 생각이 드네요 ㅠㅠ

제가 val 이나 int 에 관한 regex 를 [a-zA-Z]|[a-zA-Z]+ 로 잡아 놓으면 첫 번째 케이스에서는 인식을 하는데 두 번째 케이스에서는 인식을 못하더라구요.

yytext가 val= 까지 읽어서 문제라 생각하고 케이스를 나누었는데.. 문제는 =에 대한 regex, 숫자.. 등 regex가 늘어날수록 하나가 되면 하나가 안되고 꼬리에 꼬리를물고 해결이 되지 않네요 ㅠㅠ

보통 이런식으로 token들을 나눌때 고려해야하는 사항이나 올바른 프로세스? 에 대해서 조언좀 부탁드립니다 ㅠㅠ

jick의 이미지

뭔가 코드가 엉뚱한 데서 잘못된 것 같은데요. regex가 [a-zA-Z]|[a-zA-Z]+로 되어 있으면 뒤에 "="가 오든 공백이 오든 그걸 포함할 이유가 없죠.

동일한 문제가 발생하는 코드를 20줄 이내로 줄여서 보여주세요. (줄이는 과정 중에 문제를 발견할 확률 90%)

* 그리고 문제의 regex는 그냥 [a-zA-Z]+로 쓰는 것과 똑같지 않나요?

백연구원의 이미지

\b.*[\s].*[\=].*[;]

요구 조건은 잘 모르겠지만 일단 정규식 하나 던져봅니다.


소곤소곤

skyinyour의 이미지

저는 우선 키워드나 변수에 대해서
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 및 소스 언어에 대한 명세를 제대로 이해하고 있지 않다는 느낌이 강하게 듭니다. 제 착각이라면 사과드리겠습니다만.
일단 지금 상황에서 몇 가지만 우선 지적드리죠. 소스 언어는 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만으로 이루는 건 거의 불가능해 보이는군요. 사실 정말 제대로 하려면 전처리기 구현부터 시작해서 상당한 노력이 필요할 것 같습니다만.

skyinyour의 이미지

제가 결국 하고자 하는것은 source code를 input file로 하여 keyword 나 digit , special symbol 등을 구분하여 print 해주는 것입니다.
길이상 파일로 첨부하였습니다 ㅠㅠ
공백을 [ \t\n]+ {;} 이런식으로 처리하였는데도... 토큰이 구분이 가질 않네요 ㅠㅠ 첨부파일 한번 봐주시고 이 문제에 대해서 그리고 컴파일러를 공부중에 해보는건데 책이나 공부방향에 대해서(너무 광범위한 질문이지만... 너무 방향을못잡고있어서 제가ㅠ) 조언 부탁드립니다.. !

댓글 첨부 파일: 
첨부파일 크기
Plain text icon q&A.txt1.01 KB
jick의 이미지

lexer는 문장을 한번에 통째로 인식하려고 쓰는 도구가 아닙니다. 하나씩 잘라서 토큰에 넣도록 짜보세요.

예를 들면 "int val = 13;"이라면 flex가 "int" (예약어), "val" (ID), "=" (연산자), "13" (숫자), ";" (세미콜론...) 이렇게 다섯 개의 토큰을 돌려주도록 만드는 겁니다.

그러면 문제가 생겼을 때 어느 부분에서 문제가 생겼는지 쉽게 알 수 있습니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.