トップ «前の日記(2019-01-14) 最新 次の日記(2019-02-11)» 編集

Cocoa練習帳

iOS/iPhone/iPad/watchOS/tvOS/MacOSX/Android プログラミング, Objective-C, Cocoa, Swiftなど

2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|07|08|09|10|11|12|
2020|01|02|03|04|05|06|07|08|09|10|11|12|
2021|01|02|03|04|05|06|07|08|09|10|11|12|
2022|01|02|03|04|05|06|07|08|09|10|11|12|
2023|01|02|03|04|05|06|07|08|09|10|11|12|
2024|01|02|03|04|05|

2019-01-27 [cocoa][swift]作譜用言語PL/0 構文に対する分析子の作成

有名な『Algorithms + Data Structures = Programs』の後半を独立して誕生した『COMPILERBAU:』を翻訳した『翻訳系構成法序論』を今の電子計算機環境で取り組んでみた。

使用するプログラミング言語Swiftを選択したのだが、コンパイラの実装には少々向いていない部分があるので、まずは、一文字読み込んで処理するサンプルを記述してみた。

import Foundation
 
let parser = Parser()
import Foundation
 
class Parser {
    var ch: Character = "\0"
    var lineString: String = ""
    
    init() {
        readChar()
        S()
    }
    
    func readChar() {
        lineString = readLine()!
        ch = lineString[lineString.index(lineString.startIndex, offsetBy:0)]
        lineString = String(lineString.suffix(lineString.count - 1))
    }
    
    /*
     開式記号に対応する手続き。
     */
    func S() {
    }
}

それでは、教科書のサンプルコードを記述してみよう。

以下の約束事があるとする。

A="x"|"("B")".
B=AC.
C={"+"A}.

これは以下のようになる。

x
(x)
(x+x)
((x))
((x+(x+x)))

これを実装してみると以下となる。

/* 分析子 */
class Parser {
    var ch: Character = "\0"
    var lineString: String = ""
    
    init() {
        print("\(#function)")
        readChar()
        A()
    }
    
    func A() {
        //print("\(#function)")
        if ch == "x" {
            readChar()
        }
        else if ch == "(" {
            readChar()
            A()
            while ch == "+" {
                readChar()
                A()
            }
            if ch == ")" {
                readChar()
            }
            else {
                error()
            }
        }
        else {
            error()
        }
    }
 
    func readChar() {
        if lineString.count <= 0 {
            lineString = readLine()!
        }
        ch = lineString[lineString.index(lineString.startIndex, offsetBy:0)]
        lineString = String(lineString.suffix(lineString.count - 1))
        print(ch)
    }
    
    func error() {
        print("error: \(#function)")
        exit(-1)
    }
}

ここまでは、約束事を愚直にコードで処理しているという感じだ。

_ ソースコード

GitHubからどうぞ。
https://github.com/murakami/workbook/tree/master/mac/pl0 - GitHub

トップ «前の日記(2019-01-14) 最新 次の日記(2019-02-11)» 編集