Friday, September 26, 2014

CS205 Лаб 2: Лексер бүтээх

Зорилго:

  • Өөрийн мэддэг хэл дээрээ Си дээр бичигдсэн соорс кодыг уншиж токенуудын дараалал болгон задлах лексер бүтээх


Тайлбар:

  • Өөрийн мэддэг ямар нэг хэл дээрээ хийнэ. Заавал жава, пайтон гэхгүй. 
  • Си хэл дээр 10 мөр бүхий код бичиж файл руу хадгалах
  • Хийж буй лексертээ регуляр экспрешн ашиглаж болох газруудад нь ашиглах хэрэгтэй. Юм болгонд нь регялур экспрешн ашиглах гээд өөрсдийгөө хүндрүүлэх хэрэггүй. Дор хаяж 1-2 удаа ашиглах боломж олдоно.
  • Токен нэртэй класс зарлаж холбогдох кодуудыг бичнэ. Уг класс нь төрөл ба утга гэсэн хоёр гишүүн өгөгдөлтэй байна. Мөн дэлгэцэнд хэвлэх зориулалт бүхий гишүүн функцтэй (Жава: to_string, Пайтон: __str__, __repr__)
  • Лексер нь next_char() гэсэн функцтэй байна. Уг функц нь нэг удаа дуудагдахдаа нэг л char утга буцаана. Иймд аль мөрний аль багана дээр яваа гэдгээ санах үүднээс мөр ба багана гэсэн гишүүн хувьсагч зарлаарай. Дахин дуудагдах үед мөр ба багана гишүүн хувьсагчаа ашиглаад өмнө нь байсан байрлалаасаа үргэлжлүүлж дараагийн char утгаа буцаана. 
  • Лексер класс нь өөртөө next_token() гэдэг нэртэй гишүүн функцтэй байна. Уг функц нь next_char() функцийг дуудан буцаагдсан char утга дээр шалгалт хийж харгалзах токенг нь буцаана. Өөрөөр хэлбэл нэг удаад дуудахад нэг л токен буцаана.
  • main функцдээ төгсгөлгүй давталт хэрэгжүүлж тэрхүү давталт дотроо lexer.next_token() функцийг дуудна. next_char() функц нь файлын төгсгөлд ирэнгүүт тусгай ямар нэг тэмдэгтийг буцаана. next_token() нь тэрхүү тусгай тэмдэгтийг гараад ирэнгүүт EOF гэсэн токенг буцаана. 
  • EOF токен гараад ирэнгүүт нөгөө төгсгөлгүй давталтаасаа break хийгээд гарна. 


Псевдо код:
class Token:
  type
  value
  function to_string():
    print "TokenType: ", this.type, 
          ", Value", this.value

class Lexer:
  current_line
  current_column
  eof_value: "@"
  keywords = ['int', 'main', 'void', 'while', ... ]
  function next_char(self):
    if not end_of_file:
      if current_column >= len(current_line):
        current_line ++
        current_column = 0
      ch = read_char_value(this.current_line, 
                            this, current_column)
      current_column ++
      return ch
    else:
      return self.eof_value
  
  function concat_chars():
    word = ''
    while true:
      ch = this.next_char()
      if ch is letter or digit:
        word += ch
      else:
        break
    return word  
    
  function next_token():
    ch = this.next_char()
    if ch == "+":
      Token tok
      tok.type = "PLUS"
      tok.value = ch
      return tok
    elif ch is letter:
      word = concat_chars()
      if word in keywords:
        return Token("keyword", word)
      else:
        return Token("identifier", word)
    elif ch == "="
      ch = this.next_char()
      if ch == "=":
        return Token("equals", "==")
      else
        return Token("assign", "=")
    elif ch == "@":
      return Token("EOF", "@")
    ... 

main():
  Lexer lex
  lex.set_file("cs205.cpp")
  tok = lexer.next_token()
  print tok.to_string()
  while tok.type is not "EOF":
    tok = lexer.next_token()
    print tok.to_string()
  print "Файлын төгсгөлд хүртэл бүх токенуудыг задлаж дууслаа"
        
Дээрх код нь аль нэг хэлд хамааралгүй зөвхөн үндсэн санааг олгох үүднээс бичигдсэн псевдо код шүү. Хуулж тавиад ажиллуулах гээд үзвэл алдаа заана шүү :)
Дээр псевдо кодноос санаа аваад өөрийн мэддэг хэл дээрээ лексерын кодыг бич.

Хугацаа:
   IV долоо хоног

Багш: Ч. Эрдэнэбат
2014-9-26

No comments:

Post a Comment