EBNF语法是否适用于ANTLR3? [英] EBNF grammar to ANTLR3?

查看:94
本文介绍了EBNF语法是否适用于ANTLR3?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有用于Jass​​脚本语言的EBNF语法.
将其转换为可与ANTLR 3.5一起使用需要做些什么?
此外,有没有什么工具可以帮助我做到这一点?

I have this EBNF grammar for the Jass scripting language.
What needs to be done to convert it to work with ANTLR 3.5?
Furthermore, are there any sort of tools available to aid me in doing so?

//----------------------------------------------------------------------
// 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'+


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


Thanks in advance to any advice offered!

推荐答案

免责声明:我实际上并没有使用ANTLR,所以有人可能会提供更详细的信息.

Disclaimer: I don't actually use ANTLR, so someone that does might come by with more detailed information.

ANTLR生成递归下降解析器,因此您的语法将必须重构以消除左递归,例如在expr:

ANTLR generates recursive descent parsers, so your grammar will have to be refactored to eliminate left recursion, which you have e.g. in expr:

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

在解析expr时,解析器将尝试使用binary_op作为选项,遇到另一个expr,然后尝试递归解析该文本,而无需消耗任何输入,现在您将具有无限递归.

While parsing expr, the parser would try binary_op as an option, encounter another expr, then try to parse that recursively without having consumed any input, and you would now have infinite recursion.

这通常是通过按照以下方式重新构造语法来解决的:

This is usually dealt with by reformulating the grammar along the lines of

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

term = factor ( [*/] factor)

factor = id
         | const
         | parens
         ...

,依此类推.

这不是一个微不足道的过程,但也不是不可能做到的.

Not a trivial process, but not impossible to do either.

这篇关于EBNF语法是否适用于ANTLR3?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆