2016-03-27 9 views
2

パーサーを構築しようとしていますが、どのように動作するのかわかりません。誰かが私を正しい方向に向けて助けを必要とするので、そこからそれを拾うことができます。プロローグ内でのパーサーの作成

私はトークナイザとレクサーを持っています。

トークナイザ出力:

[INT、追加、(INT、,,, int型、B、)、=、+、B、INT、letin、(INT、、)、 =、let、b、=、10、in、add、(、a ,,, b)、int、等号、(int、a、int、b))=、if、a、==

レクサー出力:0、1、0、1、

[TYPE_INT、IDENTIFIER、OPEN_P、TYPE_INT、IDENTIFIER、COMMA、TYPE_INT、IDENTIFIER、CLOSE_P、ASSIGN、IDENTIFIER、ARITH_ADD、IDENTIFIER、TYPE_INT、IDENTIFIER、OPEN_P、TYPE_INT、IDENTIFIER、CLOSE_P、ASSIGN、LET、IDENTIFIER、ASSIGN 、IDENTIFIER、LET_IN、IDENTIFIER、OPEN_P、IDENTIFIER、COMMA、IDENTIFIER、CLOSE_P、TYPE_INT 、IDENTIFIER、OPEN_P、TYPE_INT、IDENTIFIER、COMMA、TYPE_INT、IDENTIFIER、CLOSE_P、ASSIGN、COND_IF、IDENTIFIER、LOGIC_EQ、IDENTIFIER、COND_THEN、IDENTIFIER、OPEN_P、IDENTIFIER、CLOSE_P、COND_ELSE、INTEGER、TYPE_INT、IDENTIFIER、OPEN_P、TYPE_INT、IDENTIFIER 、CLOSE_P、ASSIGN、IDENTIFIER、OPEN_P、IDENTIFIER、COMMA、INTEGER、CLOSE_P]

これでパーサを構築する必要があります。私はどのように開始するのか、どのようにパラメータ化された構造を組み込むのか分かりません。

私のルールは次のようなものです。

program --> functionList. 
functionList --> function,functionListCollection. 
functionListCollection --> functionList | []. 
function --> typeID(typeIdList),[=],expression. 
typeID --> [int],[id] | [bool],[id]. 
typeIdList --> typeID,typeIdListCollection. 
typeIdListCollection --> [,], typeIdList | []. 
expression --> [if], comparison, [then], value, [else], value. 
expression --> [let],[id],[=], value, [in], expression. 
expression --> value, extraExpression. 
extraExpression --> arithmetic | []. 
arithmetic --> [+], value | [-], value. 
comparison --> value, comparisonRight. 
comparisonRight --> [=],[=],value. 
comparisonRight --> [!], [=], value. 
comparisonRight --> [>], value. 
comparisonRight --> [>], [=], value. 
value --> [number]. 
value --> [id], valueParameters. 
valueParameters --> [(],parameters,[)]. | []. 
parameters --> value, parametersList. 
parametersList --> [,], parameters | []. 

私は、レキシードリストを取り、そのパーサーからリストを出す述語を作成しています。次に、トークンリストを調べて番号と識別子を置き換えます。どのように起動するかに関するいくつかの助けが大いに感謝されるでしょう。ありがとうございました。

答えて

2

あなたの「レクサー出力」は役に立たないだけでなく、実際に危険です。それはパーサーの一部である重要なシンボル(intなど)の名前を変更します(btw、tokenizer、およびlexerはという同義語 afaikです)。だから、単にトークナイザ出力を(一度修正し、以下を参照してください)あなたのDCGを養う:

tokens_test :- 
    Tokens = [ 
     int,add,=,a,+,33 
     % ...more source code to test - but please use writeq to show it ... 
     %,int,let,in,'(',int,a,')',=,let,b,=,10 
     %,in,add,'(',a,',',b,')',int,equal,'(',int,a,',',int,b,')',= 
     %,if,a,==,b,then,let,in,'(',a,')',else,1 
     %,int,main,'(',int,input,')',=,equal,'(',input,',',2,')' 
    ], phrase(program, Tokens). 

?- tokens_test. 
true 

私は端末として使用すると、[ID]を持っていたことから、あなたのDCGを変更し、[番号]:

id --> [I], {atom(I)}. 
number --> [N], {number(N)}. 

program --> functionList. 
functionList --> function,functionListCollection. 
functionListCollection --> functionList | []. 
function --> typeID,[=],expression. 
typeID --> [int],id | [bool],id. 
typeIdList --> typeID,typeIdListCollection. 
typeIdListCollection --> [,], typeIdList | []. 
expression --> [if], comparison, [then], value, [else], value. 
expression --> [let], id, [=], value, [in], expression. 
expression --> value, extraExpression. 
extraExpression --> arithmetic | []. 
arithmetic --> [+], value | [-], value. 
comparison --> value, comparisonRight. 
comparisonRight --> [=],[=],value. 
comparisonRight --> [!], [=], value. 
comparisonRight --> [>], value. 
comparisonRight --> [>], [=], value. 
value --> number. 
value --> id, valueParameters. 
valueParameters --> ['('],parameters,[')'] | []. 
parameters --> value, parametersList. 
parametersList --> [,], parameters | []. 

あなたは、あなたが可能性があり

typeIdList --> typeID,typeIdListCollection. 
typeIdListCollection --> [,], typeIdList | []. 

ようなサービス述語を避けることができます(下記コンマ、)区切りを持って

typeIdList --> typeID, ([,], typeIdList | []). 

でもありますが、この「簡素化」の便宜性は他の要因によって決まります。

パラメータ化された構造

ID // 0を含める方法

と数// 0は、その価値を '取り戻す' 必要がある非端末である:彼らは、ID // 1及び数// 1になり、従来、我々は、彼らが呼び出される場合、今、私たちは

... 
typeID --> [int],id(_) | [bool],id(_). 
... 
に変更する必要があります「タグ」非ターミナル(ので、我々は

id(id(I)) --> [I], % better to filter out keywords here... 
    {atom(I), \+memberchk(I,[let, etc etc])}. 
number(number(N,integer)) --> [N], {integer(N)}. 
number(number(N,float)) --> [N], {float(N)}. 

:-)シンボルを惜しまと値に使用しました

それは、そうでない場合は、それらが失われ、TYPEID // 0は現在の値(いわゆる意味属性)を「取り戻す」すべきであることは明らかです:

... 
typeID(typeID(T,I)) --> [int],id(I),{T=int} | [bool],id(I),{T=bool}. 
... 

TYPEID // 1を書くためのより良い方法を示しています。あなたは

:-)画像を取得

typeID(typeID(T,I)) --> type(T),id(I). 

type(int) --> [int]. 
type(bool) --> [bool]. 

ホープことができ

1

代わりに、

[type(int), id(add), open_p, type(int), id(a), ..... 

などのデータは、あなたが

.... 
typeID(T,A) --> [type(T)], { memberchk(T, [int,bool]) }, [id(A)], 
.... 

のテストのように、自分のルールで完全な情報を持っている、あなたのためにあなたのレクサー(*)の出力を行います。

32 ?- phrase(typeID(X,Y), [type(int), id(i)], []). 
X = int, 
Y = i. 

33 ?- phrase(typeID(X,Y), [type(bool), id(i)], []). 
X = bool, 
Y = i. 

34 ?- phrase(typeID(X,Y), [type(float), id(i)], []). 
false. 

(*)また、トークンと現在のレクサー出力を組み合わせて結合データを得ることができます。maplist

関連する問題