วันศุกร์ที่ 8 ตุลาคม พ.ศ. 2553

The Lex & Yacc

compiler หรือ interpreter สำหรับภาษาโปรแกรม(programming language) นั้นโดยปกติแล้วจะแบ่งออกเป็น 2 ส่วนคือ

  1. ส่วนที่ใช้ในการอ่าน Source Program และตรวจสอบโครงสร้างหรือ Structure ของตัว Source Program
  2. เป็นส่วนที่ใช้จัดการกับ Structure ของ Source Program

สิ่งที่ Lex และ Yacc ทำคือ

  1. ตัดคำหรือแบ่ง Source file ออกเป็น token ย่อยๆ (Lex)
  2. ตรวจสอบไวยากรณ์ของภาษาโปรแกรม โดยวิเคราะจากโครงสร้างที่แตกย่อยออกมาของ program (Yacc)

Lex – A Lexical Analyzer Generator

Lex นี้จะช่วยตัดคำ(Token) ของ source program จากการกำหนดโดย regular expressions ที่ได้รับมาจาก input stream แล้วส่งไปให้ parser ทำงานต่อ โดย source ของ Lex นี้ก็คือตาราง regular expressions และ คำหรือ Token ต่างๆที่ถูกกำหนดเอาไว้ในภาษาโปรแกรมที่ออกแบบไว้ โดยตารางนี้จะถูก translated เป็น program ที่จะใช้ในการอ่านข้อมูลจาก input stream โดยจะตัดคำ(Token) ที่ตรงกับ expressions ที่ได้กำหนดเอาไว้ โดย expression นี้จะถูกกำหนดโดย DFA หรือ deterministic finite automaton generated โดย Lex

 Yacc: Yet Another Compiler-Compiler

Yacc คือ tool ที่ใช้สำหรับอธิบายข้อมูลอินพุทให้กับ computer program ซึ่งผู้ที่ใช้ Yacc นี้จะกำหนดโครงสร้าง(Structure) ของข้อมูล input รวมไว้กับ code ที่จะถูกเรียกเอาไว้สำหรับในแต่ละ structure ที่ตรงกันสำหรับจัดการกับข้อมูลอินพุท โดยจะแบ่งออกเป็น subroutine ย่อยๆเอาไว้

 

เนื่องจาก lex กับ yacc มันเก่าแล้ว ก็เลยมีคนพัฒนา tool ตัวใหม่ๆออกมาหลายตัวดัวยกัน แต่สำหรับเอง ผมใช้

  • flex อันนี้ใช้สำหรับ lex
  • bison อันนี้ใช้สำหรับ yacc

*flex = lex,bison = yacc

ซึ่ง tool สองอันนี้เป็น OpenSource จึงสามารถนำมา compile และติดตั้งบน Linux ได้โดยไม่มีปัญหา

Flex,A fast scanner generator

Flex เป็น tool สำหรับสร้าง scanner (scanner generator) โดยprogramที่จะได้รับการยอมรับนั้นจะต้องตรงตาม lexical patterns โดยการทำงานของ flex นี้จะเริ่มจากการอ่านข้อมูล input จาก file เข้ามาหรือผ่านทาง stardard input ถ้าไม่มีการส่ง file name ให้กับ flex เพื่อใช้การอธิบายข้อกำหนดต่างๆ ก่อนที่จะทำการ generate scanner code ออกมา ดังนั้นก่อนที่จะใช้เจ้า flex นี้ได้ เราจะต้องมีการกำหนด regular expressions และชุดคำสั่งภาษา C ซึ่งเราจะเรียกว่า “RULES “ หลังจากที่กำหนด rules ต่างๆเรียบร้อยแล้วจึงใช้ flex นี้เป็น code generator ที่เราจะใช้เป็น scanner สำหรับตัดคำนั้นเอง โดย flex นี้จะ gen. ไฟล์ออกเป็นเป็นไฟล์ภาษา C ที่ชื่อว่า “lex.yy.c” ซึ่งใน file นี้จะมี routine ‘yylex()’ อยู่ภายใน จากนั้นก็เอาไฟล์ที่ได้มานี้ไปทำการ compile กับ c compiler ได้ออกมาเป็น executable ไฟล์สำหรับใช้งานอีกทีนึง

Bison, The Yacc-Compatible Parser Generator

Bison คือ parser generator ที่แปลงส่วนอธิบาย grammar ของ LALR context-free grammar (LALR parser generator เป็น software tool ที่ใช้ในการอ่าน BNF Grammar เข้ามาแล้ว generate code ให้เป็น LALR parser) ออกมาเป็น C program ที่ใช้ในการวิเคราะห์ไวยากรณ์

*Bison นี้ถูกพัฒนามาจาก Yacc ซึ่งการเขียน Yacc Grammar นี้จะสามารถนำไปใช้ได้กับ Bison ได้โดยไม่ต้องมีการเปลี่ยนแปลงเลย ซึ่งทำให้ผู้ที่มีความคุ้นเคยกับ Yacc นั้นสามารถเปลี่ยนมาใช้ Bison ได้โดยง่าย

วันนี้ง่วงนอนแระ เอาไว้รอบหน้าผมจะเอา Flex/Bison มาอธิบายให้ฟังกันอย่างละเอียดกันไปเลยทีเดียวละกันนะคับ อิอิ

วันพฤหัสบดีที่ 7 ตุลาคม พ.ศ. 2553

วิธีกำหนด JFrame ให้อยู่กลางจอ

ถ้าเราจะจัดให้ JFrame ของเราอยู่กลางหน้าได้โดยเรียกใช้ Function getToolkit().getScreenSize() เราจะได้ขนาดของหน้าจอกลับมาในรูปของ Dimention Object (ไอ้เจ้าฟังก์ชั่น getToolkit() ของ JFrame นี้มัน inherit มาจาก Window) ลองมาดูตัวอย่างกันคับ

Dimension d = getToolkit().getScreenSize();

int screenWidth = d.width;

int screenHeight = d.height;

หลังจากนั้นเราก็มาหาตำแหน่งกึ่งกลางของจอโดยเอาค่าความกว้างกับความยาวมาหารด้วย2

int centerX = screenWidth/2;

int centerY = screenHeight/2;

แล้วก็มาหาตำแหน่งที่เราจะวาง JFrame เพื่อให้ frame นั้นอยู่กลางหน้าจอ เนื่องจากว่าเวลาเรากำหนดตำแหน่งของ frame ตำแหน่งที่เรากำหนดจะเป็นตำแหน่งของมุมซ้ายด้านบนของ frame มันเลยไม่อยู่ตรงกลางให้เรา (55+) ดังนั้นถ้าเราจะกำหนดตำแหน่งกึ่งกลางจอให้กับ JFrame ตรงๆนั้น frame ก็จะไม่ได้อยู่ตรงกลางเราจึงต้องคำนวนหาตำแหน่งของมันซะก่อน โดยลบค่าของ centerX และ centerY ด้วยขนาดครึ่งนึงของ frame ตามลำดับดังนี้

int xPos = centerX – frame.getWidth() / 2;

int yPos = centerY – frame.getHeight() / 2;

*สมมติให้ frame เป็น reference ของ JFrame

และแล้วเราก็จะได้ตำแหน่งที่จะต้องกำหนดให้กับ JFrame แว้ววว… ก็มาsetค่าตำแหน่งให้กับมันเลยคับ

frame.setLocation(xPos,yPos);

ก็เป็นอันว่า frame ของเราก็จะอยู่ตรงกลางเป็นที่เรียบร้อยละค๊าบบ.. มาดูตัวอย่างกันดีกว่า อิอิ

import javax.swing.*;

import java.awt.*;

public class TestJFrame extends JFrame {

  public static void main(String[] agrs) {

    JFrame f = new JFrame(“Centering JFrame”);

    f.setSize(200,200);

    Dimension d = f.getToolkit().getScreenSize();

    int screenWidth = d.width;

    int screenHeight = d.height;

    int centerX = screenWidth / 2;

    int centerY = screenHeight / 2;

    int xPos = centerX – f.getWidth() / 2;

    int yPos = centerY – f.getHeight() / 2;

    f.setLocation(xPos,yPos);

    f.setVisible(true);

  }

}

วันจันทร์ที่ 26 กรกฎาคม พ.ศ. 2553

Style การเขียนโปรแกรมเมื่อใช้ &

โปรแกรมเมอร์ C++ บางคนชอบเขียนเครื่องหมาย & ต่อท้ายชนิดข้อมูลมากกว่าที่จะเขียนไว้หน้าตัวแปร เช่น

void swap(int& a,int& b);

และนอกจากนี้บางคนยังนิยมเขียนวิธีนี้กับ Pointer operator ด้วยเช่น

float* p;

จุดประสงค์เพื่อจะให้มีความแตกต่างว่าเป็นข้อมูลชนิดpointer แต่วิธีการนี้อาจก่อให้เกิดความสับสนกับการประกาศเพราะ & และ * ใช้กับลิสต์ของตัวแปรไม่ได้เช่น ถ้าต้องการประกาศตัวแปร Integer 2ตัว เป็นpointer

int* a,b;

จะทำไม่ได้เพราะ b จะเป็นตัวแปรแบบ Integer ธรรมดาไม่ใช้ตัวแปรแบบ Pointer เพราะ & และ * จะใช้ได้กับตัวแปรทีละตัวเท่านั้น

สำหรับการเขียน &,* นั้นจะเขียนแบบไหนก็ได้เพราะ compiler จะตีความหมายเหมือนกัน

วันอาทิตย์ที่ 25 กรกฎาคม พ.ศ. 2553

การคืนค่า Function แบบ References

     นอกจากจะใช้พารามิเตอร์ Reference ได้แล้ว ยังสามารถใช้วิธีการนี้กับการคืนค่าของfunctionได้ เราสามารถทำได้โดยใช้เครื่องหมาย & นำหน้าชื่อ function เช่น prototype ของ f() ที่คืนค่า Integer แบบ Refernce

int &f();

     ในfunctionที่คืนค่าแบบ Reference นั้น compiler จะรู้เองว่าต้องคืนค่าที่เป็น address ของ object แทนที่จะเป็นค่าของมัน เช่น

int &f(){

  int i;

  cin >> i;     // get a value for i

  return i;     // automaticity returns reference to i

วันจันทร์ที่ 19 กรกฎาคม พ.ศ. 2553

จัดไป1เพลง กับวันเหง๊าาาา….เหงา

 

 

 

 

 

 

 

 

 

 

 

ในยามที่เราได้พบกัน ฉันจะเปรียบเธอเป็นเช่นดอกไม้
ในยามที่เราได้รักกัน ฉันจะปลูกต้นรักไปทั้งใจ
เวลาที่มีหยาดฝนโปรยปราย ฉันจะปรากฏกายข้างเธอไม่ห่างไปไหน
เวลาที่มีเรื่องร้อนใจ ฉันจะปัดและเป่าให้เธอจนชื่นใจ

ถึงแม้วันใดไม่มีฉันอยู่ ให้เธอรู้ความรักคงอยู่ไม่ห่างไปไหน
ต้นรักที่ฉันปลูกไว้ข้างใน หากเธอคงรักนั้นไว้ คอยดูแลรักฉันไว้... โว๊ะ โอ โอะ..

ความรักที่มีให้กัน ถ้าเธอคอยรักและอยู่เคียงข้างกัน
แค่ให้ความอบอุ่น และรักที่มีนั้นช่วยพาเราไป โว๊ะ โอ โอะ..
ความรักส่งไปให้เธอ แด่เธอที่รัก มั่นคงไว้เสมอ
ด้วยความรักที่มีแค่เรา ข้างกันและกัน

แค่เพียงจับมือสบสายตา รักจะพาให้เราล่องลอยสู่ความฝัน
ไม่มีสิ่งใดที่ล่ำค่า มากไปกว่าต้นรักที่เรามีให้กัน

วันเสาร์ที่ 17 กรกฎาคม พ.ศ. 2553

Newton – Raphson Method

การแก้ปัญหาทางคณิตศาสตร์ วิทยาศาสตร์ บางครั้งจะต้องแก้หาค่า x จากสมการ f(x)=0 ถ้าหากเป็นfunction กำลังสองทั่วไปอาจใช้ สูตรมาแก้สมการได้ แต่ถ้าเป็นfunctionที่มีกำลังสูงขึ้นจะไม่มีสูตรที่แน่นอน จึงมีวิธีการทางการวิเคราะห์เชิงตัวเลข(Numerical Analysis) มาแก้ปัญหาสำหรับเทคนิคที่นิยมใช้กันจะเป็นวิธีของนิวตัน หรือ Newton – Raphson Method ซึ่งจะใช้เส้นสัมผัสเส้นโค้ง y=f(x) ที่จุด f เข้าใกล้ศูนย์มาช่วยประมาณค่า

สมการของเส้นสัมผัสของกราฟ y=f(x) ที่จุด x=a หรือเส้นสัมผัสที่ผ่านจุด(a,f(a)) จะมีสมการเป็น
                        L(x) = f(a) – f‘(a) (x-a)

image

 

 

จากภาพ เป็นfunction y = x^2
และเส้นสัมผัสของ f(x) ที่จุด x=5

 

 


 

 

ขั้นตอนของ Newton – Raphson

การประมาณค่ารากของ function จากสมการ f(x) = 0 จะทำโดยอาศัยเส้นสัมผัส เส้นโค้ง y = f(x) ถ้าหากเริ่มต้นประมาณค่า x ด้วย x0 ให้ลากเส้นสัมผัสที่จุด (x0,f(x0)) เส้นสัมผัสจะตัดแกน x1 ซึ่ง x1 นี้จะมีค่าใกล้เคียงกับรากของสมการด้วย เรามาดูตัวอย่างในรูปกันคับ

image
















จากนั้นให้ใช้ x1 ประมาณค่าต่อไปโดยลากเส้นสัมผัสที่จุด (x1,f(x1)) ทำให้เส้นสัมผัสมาตัดแกน x ที่จุด x2 และใช้ x2 นี้ประมาณค่าต่อไปอีก ซึ่งจะทำให้ค่า x ที่ได้ใกล้เคียงคำตอบมากขึ้นเรื่อยๆ ดังนั้นถ้าทำขั้นตอนเหล่านี้ n+1 ครั้ง จะได้ค่าประมาณเป็น x ที่ n+1 ซึ่งเกิดจากการประมาณค่าจากจุด x ที่ n โดยสมการเส้นสัมผัสที่จุด (xn,f(xn)) คือ

                              y – f(xn) = f’(xn) (x-xn)

เนื่องจากเส้นสัมผัสที่ตัดแกน x นั้นค่า y จะเท่ากับศูนย์อย่างในรูป ดังนั้น
                             0 – f(xn) = f’(xn) (x-xn)
                                - f(xn) = f‘(xn) (x-xn)
                                - f(xn) = f’(xn) * x – f’(xn) * xn
                             f(xn) * x = f’(xn) * xn – f(xn)
                                       x = xn – f(xn) / f’(xn)

Overriding Method

Methods defined in a superclass can be overridden by methods defined in a subclass. Here is the definition:

Definition Overiding: Overriding refers to the introduction of an instance method in a subclass that has the same name,signature,and return type of a method in the superclass. Implementation of the method in the subclass replaces the implementation of the method in the superclass.

Overriding is different from overloading.Overriding is concerned with methods of different classes that have an inheritance relationship.In overriding,methods share the same name,signature,and return type.In contrast,overloaded methods are part of the same class,but have different signatures.

We can illustrate the distinction between overloading and overriding in the following manner. In

class A{
        public void m1(){
            //statement
        }
        public void m1(int i){
            //statement
        }
    }

class A contain two overloaded methods.An instance of A can access both methods,depending on the arguments of the method invocation,so

A a = new A();
a.m1();            //invoke m1()
a.m1(1);          //invoke m1(int)

Now,let us assume that we have the two classes

class B{
    public void m2(){
        //statement
    }
}
class C{
    public void m2(){
        //statement
    }
}

Implementation of method m2() in class B is overridden by another implementation of method m2() in class C. For a given object,one but not both of the implementations of method m2() is available, depending on the class of the object.

B b = new B();
C c = new C();
b.m2(); //invoke the m2() in class B
c.m2(); //invoke the m2() in class C

Overriding a method with another method of different signature or return type is not allowed.For example,the following code segment will cause a compilation error:

class B{
    public void m3(int i){
    }
}
class C{
    public void m3(char c){
    }
}