コンパイラの本に必ずといっていいほど取り上げられる、字句解析プログラムLex、sfl2vlもこれを使って字句解析をしているけれど、実はLexは、かなりレベルの低い字句解析しかできない。具体的には、これは、モードをもったパターンマッチングしかできないといっても過言ではない。
sfl2vlでは、状況に応じて、Lexのモードでは対応できない部分をCのコードで文法を解析しつつ、字句解析のモードを決定するという回りくどいやり方をしている。
もともと、C言語では、すべての識別子はコンパイル単位で一意でなくてはならないという縛りがあったので、Lexのやり方で十分だったが、もう少し複雑な構造を持つ言語では、Lexの仕組みだけでは無理がある。
今回、ちょっと困ったのが、名前付きの引数渡しをサポートするときに、サブモジュールの制御入力起動において、例えば、
alu.exec(fun=ADD, inA=PC, inB=0x01)
というような記述をしたいという場合、ここで、名前は、サブモジュール内の名前を用いる必要があり、シンボルテーブルはサブモジュールのものを参照するのが正当だが、Lexで状況に応じてシンボルテーブルを切り替えるには、文法を深く解析することになり、あまりストレートではない。
Lex側で、全部のシンボルを文脈を無視して、単にシンボルとして扱い、それをYaccに渡すと、こんどは、Yaccが一つ先のトークンまでしか見ないという制限があって、文法の曖昧さが解消できない。
やはり、Lexを捨てて、独自に字句解析した方が素直な気がするが。。毎回、この手の問題にぶつかるたびに思うが、なかなか踏み切れないものだ。
とりあえず、名前付き引数はサブモジュールの呼び出しでは使えないことにしておく。 ;-d
sfl2vlでは、状況に応じて、Lexのモードでは対応できない部分をCのコードで文法を解析しつつ、字句解析のモードを決定するという回りくどいやり方をしている。
もともと、C言語では、すべての識別子はコンパイル単位で一意でなくてはならないという縛りがあったので、Lexのやり方で十分だったが、もう少し複雑な構造を持つ言語では、Lexの仕組みだけでは無理がある。
今回、ちょっと困ったのが、名前付きの引数渡しをサポートするときに、サブモジュールの制御入力起動において、例えば、
alu.exec(fun=ADD, inA=PC, inB=0x01)
というような記述をしたいという場合、ここで、名前は、サブモジュール内の名前を用いる必要があり、シンボルテーブルはサブモジュールのものを参照するのが正当だが、Lexで状況に応じてシンボルテーブルを切り替えるには、文法を深く解析することになり、あまりストレートではない。
Lex側で、全部のシンボルを文脈を無視して、単にシンボルとして扱い、それをYaccに渡すと、こんどは、Yaccが一つ先のトークンまでしか見ないという制限があって、文法の曖昧さが解消できない。
やはり、Lexを捨てて、独自に字句解析した方が素直な気がするが。。毎回、この手の問題にぶつかるたびに思うが、なかなか踏み切れないものだ。
とりあえず、名前付き引数はサブモジュールの呼び出しでは使えないことにしておく。 ;-d