0

Jassスクリプト言語用のこのEBNF文法があります。
ANTLR 3.5で動作するように変換するには何をする必要がありますか?
さらに、そうするのに役立つツールはありますか?

//----------------------------------------------------------------------
// Global Declarations
//----------------------------------------------------------------------
program  ::= file+
file     ::= newline? ( declr newline )* func*
declr    ::= typedef
           | globals
           | native_func
typedef  ::= 'type' id 'extends' ( 'handle' | id )
globals  ::= 'globals' newline global_var_list 'endglobals'
global_var_list
         ::= ( 'constant' type id '=' expr newline | var_declr newline )*
native_func
         ::= 'constant'? 'native' func_declr
func_declr
         ::= id 'takes' ( 'nothing' | param_list ) 'returns' ( type | 'nothing' )
param_list
         ::= type id ( ',' type id )*
func     ::= 'constant'? 'function' func_declr newline local_var_list statement_list 'endfunction' newline

//----------------------------------------------------------------------
// Local Declarations
//----------------------------------------------------------------------
local_var_list
         ::= ( 'local' var_declr newline )*
var_declr
         ::= type id ( '=' expr )?
           | type 'array' id
statement_list
         ::= ( statement newline )*
statement
         ::= set
           | call
           | ifthenelse
           | loop
           | exitwhen
           | return
           | debug
set      ::= 'set' id '=' expr
           | 'set' id '[' expr ']' '=' expr
call     ::= 'call' id '(' args? ')'
args     ::= expr ( ',' expr )*
ifthenelse
         ::= 'if' expr 'then' newline statement_list else_clause? 'endif'
else_clause
         ::= 'else' newline statement_list
           | 'elseif' expr 'then' newline statement_list else_clause?
loop     ::= 'loop' newline statement_list 'endloop'
exitwhen ::= 'exitwhen' expr
return   ::= 'return' expr?
debug    ::= 'debug' ( set | call | ifthenelse | loop )

//----------------------------------------------------------------------
// Expressions
//----------------------------------------------------------------------
expr     ::= binary_op
           | unary_op
           | func_call
           | array_ref
           | func_ref
           | id
           | const
           | parens
binary_op
         ::= expr ( [+-*/><] | '==' | '!=' | '>=' | '<=' | 'and' | 'or' ) expr
unary_op ::= ( '+' | '-' | 'not' ) expr
func_call
         ::= id '(' args? ')'
array_ref
         ::= id '[' expr ']'
func_ref ::= 'function' id
const    ::= int_const
           | real_const
           | bool_const
           | string_const
           | 'null'
int_const
         ::= decimal
           | octal
           | hex
           | fourcc
decimal  ::= [1-9] [0-9]*
octal    ::= '0' [0-7]*
hex      ::= '$' [0-9a-fA-F]+
           | '0' [xX] [0-9a-fA-F]+
fourcc   ::= '' ' .{4} ' ''
real_const
         ::= [0-9]+ '.' [0-9]*
           | '.' [0-9]+
bool_const
         ::= 'true'
           | 'false'
string_const
         ::= '"' .* '"'
parens   ::= '(' expr ')'

//----------------------------------------------------------------------
// Base RegEx
//----------------------------------------------------------------------
type     ::= id
           | 'code'
           | 'handle'
           | 'integer'
           | 'real'
           | 'boolean'
           | 'string'
id       ::= [a-zA-Z] ( [a-zA-Z0-9_]* [a-zA-Z0-9] )?
newline  ::= '\n'+


提供されたアドバイスに事前に感謝します!

4

3 に答える 3

1

文法記述言語は本当に小さいです。それらの文法には、十数かそこらの規則しかありません。

あなたができること(私がしたこと)は、ANTLRを使用してEBNF表記の文法を記述し、それを使用して、所有しているものをANTLR文法に変換することです。

それは約1日か、せいぜい2日であるはずです。

于 2013-03-01T14:26:00.743 に答える
1

免責事項:私は実際にはANTLRを使用していないので、使用している人がより詳細な情報を持って来る可能性があります。

ANTLRは再帰下降パーサーを生成するため、左再帰を排除するために文法をリファクタリングする必要がありますexpr

expr     ::= binary_op
...
binary_op
         ::= expr ( [+-*/><] | '==' | '!=' | '>=' | '<=' | 'and' | 'or' ) expr

解析中exprに、パーサーはbinary_opオプションとして試行し、別のexprを検出し、入力を消費せずにそれを再帰的に解析しようとします。これで、無限再帰が発生します。

これは通常、次の行に沿って文法を再定式化することによって処理されます

expr     ::= binary_op
...
binary_op
         ::= term ( [+-] term )

term = factor ( [*/] factor)

factor = id
         | const
         | parens
         ...

等々。

些細なプロセスではありませんが、どちらも不可能ではありません。

于 2013-03-01T01:27:18.637 に答える
1

あなたはアドバイスを求めましたが、あなたの質問は奇妙なことにAntlr3.5に固有のものです。Antlr 3.5を使用する必要がありますか?文法を何に使用するかを知ることは役に立ちます:単純な構文検証または完全なインタプリタ?

Antlr 4の使用を検討できる場合は、そうする必要があります。左因数分解されたルールをAntlr3よりも適切に処理し、Antlrを学習しているように見えるため、Antlr4IMOを簡単に取得できます。本当にASTが必要な場合は、Antlr3を使用してください

残念ながら、自動変換ツールは、せいぜい、文法を開発するための悪い出発点になります。

どこから/どのように開始するかについては、Java文法のコピー(Antlr 3.5の場合はjava.g 、Antlr 4の場合はjava.g4)を入手して、実用的な例として使用することをお勧めします。 java文法は、どのように進めるかについての明確なアイデアを提供するはずです。

于 2013-03-01T05:05:17.640 に答える