- 2022年8月9日(火)13:30~15:30
- 2022年8月11日(木)13:30~15:30
- Node.jsが動く環境を用意しておく
- リポジトリがダウンロードできるよう、Gitをインストールしておく
- 【演習1】理想のプログラミング言語の企画書を書いてみよう (資料なし)
- 逆ポーランド記法(RPN)について
- [Wikipedia] https://bit.ly/3RXYH3H
下記のヒントを見ないで作ることを推奨するが、見ても問題ない。
- (1) 文字列を空白でトークンに区切る
- (2) トークンを1つ読む
- (3) 数値なら、スタックに積む
- (4) 演算子なら、スタックから2つ値を取り出して計算してスタックに積む
- (5) トークンが空でなければ(2)に戻る
演習2で作ったRPN電卓を簡易スタック言語に改良しよう! 以下の命令を実装すること。
- 変数の代入 --- (値) (変数名) set
- 変数の取得 --- (変数名) get
- 変数の取得(簡易記法) --- %(変数名)
- 画面表示 --- (値) print
- 演習3で作ったスタック言語を altJS にして、ブラウザで動くようにする
- 生成したJavaScriptが見える形で出力しよう
なでしこのソースコードをダウンロード。
$ git clone --recursive https://github.com/kujirahand/nadesiko3.git
$ cd nadesiko3
$ npm install
TypeScriptのソースコードをJavaScriptに変換しつつ、WebPackでソースコードを1つにまとめる方法。
# コンパイル
$ npm run build:webpack
# ブラウザ上でなでしこを実行
$ npm start
例えば以下のプログラムが動くように、「RPN計算」命令を追加してみよう!
「30 50 * 5 +」をRPN計算して表示。
JavaScriptのパッケージマネージャーnpmでプロジェクトを作成。
# プロジェクトの作成
$ mkdir nadesiko3-fuga && cd nadesiko3-fuga
$ npm -f init
$ npm install nadesiko3 --save-dev
# プロジェクトの公開
$ npm publish
【手順1】字句解析器に手を加える
$ vim core/src/nako_lex_rule.mts
上記に以下のコードを追加。
{ name: ‘incNum’, pattern: /\+\+/ },
【手順2】構文解析にルールを追加
$ vim core/src/nako_parser3.mts
メソッド ySentence に以下のコードを追加。 これは、構文木にincNumというコードを追加するもの。
if (this.accept(['word', 'incNum'])) {
return {
type:'incNum',
name: this.getVarNameRef(this.y[0]).value,
... this.peekSourceMap()
}
}
【手順3】コード生成を修正
$ vim core/src/nako_gen.mts
メソッド _convGen ()のswitch文にコード生成処理を追加
case 'incNum': code += this.genVar(node.name as string, node) + '++;'; break;
最後にビルドしてインクリメント演算子が実装できたか確認してみよう。
$ npm run build:webpack
$ npm start
# PEGパーサのインストール
$ npm install -g pegjs
# プログラムを作る
$ touch sisoku.pegjs
# コンパイル
# pegjs sisoku.pegjs
- PEGのオンライン文法定義
start = add
add = left:mul "+" right:add { return left + right; }
/ left:mul "-" right:add { return left - right; }
/ mul
mul = left:val "*" right:mul { return left * right; }
/ left:val "/" right:mul { return left / right; }
/ left:val "%" right:mul { return left % right; }
/ val
val = _ "(" _ expr:add _ ")" _ { return expr }
/ _ nums:[0-9]+ _ { return parseInt(nums.join('')); }
_ "whitespace" = [\s\n ]*
PEGで変数機能とPRINT構文を実装してみよう。
- PRINT (式)
- 変数 = 式