OpenHSP コンパイラは、組み込み命令 (mes など) や、#deffunc
等により定義される命令を処理してから命令文などの構文解析を行うため、構文解析の段階で変数と命令 (および関数・システム変数) を区別できる。一方、フォージェリはそのような前処理なしに構文解析を行うため、変数と命令を区別できない。
この違いから、一部の文の解釈が曖昧になる問題が生じる。例えば、以下の3パターンがある。
// x が命令なら、命令 x に引数式 -y を渡す命令文
// そうでなければ、変数 x から y を引く複合代入文
x-y
// x が命令なら、命令 x に引数式 *y (ラベル) を渡す命令文
// そうでなければ、変数 x に y をかける複合代入文
x*y
// x が命令なら、命令 x に引数式 (y)=z を渡す命令文
// x が変数なら、配列要素 x(y) に z を代入する代入文
x(y)=z
- パーサは誤りのあるソースコードを可能な限り解釈すること
- パーサは中途半端なソースコード (エディタで編集している途中のコード) にも使う。
- トークン列が構文的に正しいと考えてはいけない。
- 構文エラーがなるべく波及しないようにする。
- パーサは停止すること
- 上位のルールを呼び出したり、ループの先頭に戻ったりする (「遡る」) 部分は特に注意。
- 遡る前に1つ以上のトークンを bump するようにしておけば、無限ループにはならない。
- パーサは事前条件を使ってよい
- 空許容な (トークンを1つも bump することなく成功する可能性がある) 関数は事前条件を持たない。
- 空許容でない関数は、先読みに関する事前条件を持っていてもよい。
- 例えば
parse_name
は次のトークンが識別子のときにだけ呼ばれると考えていい。 - 事前条件は必ず関数の先頭の
assert!
で明示すること。