繁体   English   中英

EBNF语法是否适用于ANTLR3?

[英]EBNF grammar to ANTLR3?

我有针对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'+


在此先感谢您提供的任何建议!

免责声明:我实际上并没有使用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
         ...

等等。

这不是一个微不足道的过程,但也不是没有可能。

您寻求任何建议,但您的问题奇怪地是针对Antlr 3.5的。 您是否需要使用Antlr 3.5? 这将有助于您了解语法的用途:简单的语法验证或全面的解释器?

如果可以考虑使用Antlr 4,则应该这样做。 与Antlr 3相比,它处理左因子分解规则的能力更好,并且,由于您似乎只是在学习Antlr,因此Antlr 4 IMO会更容易掌握。 如果您确实需要AST,请选择Antlr 3

不幸的是,自动转换工具充其量只能为您开发语法提供一个不好的起点。

关于从何处开始/如何开始,最好的建议是获取Java语法的副本(对于Antlr 3.5为java.g或对于Antlr 4为java.g4 )作为工作示例- Jess看起来与Java语法应该给您一个清晰的思路,如何进行。

语法描述语言确实很小。 他们的语法只有十几条规则。

您可以做的(我已经做过的事情)是使用ANTLR为EBNF表示法编写语法,然后使用该语法将您拥有的内容转换为ANTLR语法。

这应该是大约一天的工作,或者最多两个工作日。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM