2012-11-02 12 views
5

こんにちは私はこのような文法を持つ単純な言語のパーサーを実装しようとしています。パーサーの実装

program ::= "program" declarations "begin" statements "end" 
declaration ::= "var" ident "as" type 
type ::= "string" | "int" 

私はどのようにタイプ文法を書いていますか?

program(prog(DECLS, STATS)) --> 
[ 'program' ], declarations(DECLS), 
[ 'begin' ], statements(STATS), [ 'end' ]. 

declaration(decl(IDENT, TYPE)) --> 
[ 'var' ], ident(IDENT), [ 'as' ], type(TYPE). 
+0

:それとも、このスキーマ(用心、未テストコード)を使用して、より直接的いることを扱うことができますワードパッド.spファイル – user1794576

+0

申し訳ありませんがプロローグ – user1794576

答えて

2
type(string) --> ['string']. 
type(int) --> ['int']. 

(実際'が必要とされていない)

あなたは|または;を使用することができますが、それはあなたが見つかった型を返す方法が複雑になります。

+0

これはまさに私が感謝のために探していたものです – user1794576

+0

私もこれをやろうとしています。assign_stmt :: = ident operator exprお手伝いできますか? – user1794576

+0

@ user1794576非常に簡単ですね。 'assign_stmt(...):文法から左回帰を削除すべき式のためのident(...)、operator(...)、expr(...)。':https://en.wikipedia .org/wiki/Left_recursion#Removing_left_recursion –

2

文法が不明な場合があります。実際、キーワードが識別子のような他のトークンからどのように分離されるかは定義しません。キーワードから識別子を分離する必要のないプログラミング言語があります。いくつかの空白やレイアウト文字が必要な他のプログラミング言語もあります。

あなたの場合、「varaasint」は有効な宣言ですか?あなたの文法はそれを示唆しています。または、 "var a as int"と書く必要がありますか?

this answer for moreを調べるとよいでしょう。

1

あなたはstatementsルールが不足しています。

とにかく、DCGの規則はPrologでの単純な構文の砂糖です。次に、好きなPrologの機能を使用できます。あなたは、コンパクトな文法を維持する必要がある場合:

type(type(T)) --> [T], {memberchk(T, [int, string])}. 

中括弧は、文法規則と一般的なプロローグを混在させることができます。

あなたの文法は、あなたの入力を分割して、を捨てて、の空白を破棄した場合にのみ有効です。私はSICStusを使用する上でのルールと文法を変更したときit..Iはただで文法を編集していますテストする

program(prog(DECLS, STATS)) --> 
    s, "program", s, declarations(DECLS), 
    s, "begin", s, statements(STATS), s, "end", s. 

declaration(decl(IDENT, TYPE)) --> 
    "var", s, ident(IDENT), s, "as", s, type(TYPE). 

declarations([D|Ds]) --> declaration(D), declarations(Ds). 
declarations([]) --> []. 

type(type(int)) --> "int". 
type(type(string)) --> "string". 

% skip 1 or more whitespace 
s --> (" " ; "\n"), (s ; []). 
関連する問題