コンパイラの理論、実際のエントリー:簡単な四則演算のコンパイラを書くためにはJavaScriptを使用し(c)のシミュレーション実行

今すぐアセンブリコードと機械の指示対応するので、機械語命令の実行をシミュレートするために、CPUを見て、私たちは、シミュレータのアセンブリコードの直接の実装を作成することができます。
シミュレータを作成する前に、最初に関連するディレクティブの動作を説明します。

  • スタック

メモリにおいて、スタックは、挿入および欠失によって特徴付けられるだけであり、2つだけの操作はプッシュとポップ、同じ端部で動作させることができます。

  • 押す

プッシュ命令の効果は、スタックオペランドをプッシュすることです。

  • ポップ

アクションポップ命令は、オペランドスタックをポップすることです。

  • 加えます

アクションは、指示操作を二回スタックに結果をプッシュし、次いで、二つのオペランドAおよびBをポップアップ、ポップ、次いで+ bを行う行われる加えます。

  • サブ

スタックに結果をプッシュし、次いで、B - アクション命令を2回サブポップ操作を行っポップ二つのオペランド及びB、及び次いで行います。

  • 私に

アクションMUL命令操作を2回、ポップ二つのオペランドAおよびBをポップし、次に* bを実行し、スタックに結果をプッシュ行われます。

  • DIV

動作指示を2回サブポップ操作を行っポップ二つのオペランドおよびB、次いで/ Bを実行し、スタックに結果をプッシュします。

すべての4つの命令は、操作が終了した説明、それはそれほど単純ではないのですか?

コードの実装

注:導入する必要がある最初の二つの記事字句解析や構文解析コード

function CpuEmulator(instructions) {
    this.ins = instructions.split('\r\n')
    this.memory = []
    this.re = /^(push)\s\w+/
    this.execute()
}

CpuEmulator.prototype = {
    execute() {
        this.ins.forEach(i => {
            switch (i) {
                case 'add':
                    this.add()
                    break
                case 'sub':
                    this.sub()
                    break
                case 'mul':
                    this.mul()
                    break
                case 'div':
                    this.div()
                    break                
                default:
                    if (this.re.test(i)) {
                        this.push(i.split(' ')[1])
                    }
            }
        })
    },

    add() {
        const b = this.pop()
        const a = this.pop()
        this.memory.push(a + b)
    },

    sub() {
        const b = this.pop()
        const a = this.pop()
        this.memory.push(a - b)
    },

    mul() {
        const b = this.pop()
        const a = this.pop()
        this.memory.push(a * b)
    },

    div() {
        const b = this.pop()
        const a = this.pop()
        this.memory.push(a / b)
    },

    push(x) {
        this.memory.push(parseInt(x))
    },

    pop() {
        return this.memory.pop()
    },

    getResult() {
        return this.memory[0]
    }
}

const tokens = lexicalAnalysis('(100+  10)*  10-100/  10      +8*  (4+2)')
const writer = new AssemblyWriter()
const parser = new Parser(tokens, writer)
const instructions = parser.getInstructions()
const emulator = new CpuEmulator(instructions)
console.log(emulator.getResult()) // 1138

おすすめ

転載: www.cnblogs.com/woai3c/p/11110653.html