Monday, September 04, 2006

Antlr

ช่วงนี้มีโจทย์งาน ที่ต้องเขียน interpreter เอง
โดยตัว language ที่เขียน จะใช้สำหรับ generate รายงาน แบบ text
(ที่ออกทาง line printer หรือ dot matrix)

ตัว syntax ลอกแบบมาจาก Ingres report writer
(ที่ลอก ก็เพราะมี report เก่าหลายร้อย report
ที่อยากจะ switch database ไปใช้ database ตัวอื่น)
หน้าตา language ก็ประมาณนี้

.name xxxx
.query select name, salary from person
.header page
.pr '========================' .newline
.pr ' name salary .newline
.pr '========================' .newline
.header name
.tab 10
.print name
.newline
.detail
.tab 20
.print salary ("zzz,zzn.nn");
.newline
.footer page
.pr '========================' .newline
.pr ' total'
.tab 20
.pr sum(salary)
.newline


ตอนแรกก็ชั่งน้ำหนักก่อนเลย ว่าจะ implement ด้วยอะไรดี
ระหว่าง java กับ python
ตัว java นี่ของตายอยู่แล้ว
ส่วน python นี่ที่เลือก เพราะอยากเรียนรู้

สุดท้ายก็เลือกใช้ java เพราะว่ากรอบระยะเวลา
ที่อยากให้เสร็จภายใน 1 เดือน

tool ที่เลือกใช้ในส่วน parser ก็คือ Antlr
โดยข้อดีของการใช้ antlr ที่เห็นชัดๆ
ก็คือ meta syntax ของ antlr ที่ใช้เขียน lexer, parser, tree parser
มันเป็นตัวเดียวกัน ก็เลยง่ายในการเรียนรู้

เวลาเขียน parser ก็จะแยกเป็น 2 ขยัก
pass แรก ก็คือ compile language ให้เป็น AST (Abstract Syntax Tree) ก่อน
ขยักที่ 2 ก็คือตอน runtime
ซึ่งจะใช้ tree walker ท่องไปตาม AST ที่ได้จากข้อ 1

เริ่มแรกสุดผมก็ใช้วิธี top down
ทำ prototype ก่อน
define เฉพาะ gramma หลักๆที่อยากให้ prototype แสดงผลได้
หลังจากทำไปสัก 2 วัน ก็พบว่า
วิธีนี้มีข้อเสียมากกว่าข้อดี
ข้อดี ก็คือได้เห็นผลลัพท์ไว
ข้อเสีย ก็คือ gramma ของ feature ที่เพิ่มมาทีหลัง
มันจะ conflict กับ gramma ชุดแรก ได้ง่าย

ตอนนี้ก็เลยเปลี่ยนไปใช้วิธี bottom up
นั่ง define term ใล่จาก primitive datatype
ขึ้นมาเป็น expression ->ใล่ขึ้นมาเป็น statement
แล้วก็ใช้ junit เขียน test ประกบไปเรื่อยๆ
ทำให้ refactor ได้ง่ายขึ้น เพราะมี unit testing คอย proof ความถูกต้องอยู่

Related link from Roti

No comments: