2013-03-01 3 views
0

У меня есть эта грамматика EBNF для языка сценариев Jass.
Что нужно сделать, чтобы преобразовать его в ANTLR 3.5?
Кроме того, существуют ли какие-либо инструменты, которые помогут мне в этом?

EBNF грамматика ANTLR3?

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


Спасибо заранее к любому совету предлагается!

+0

Как оказалось, грамматики ANTLR почти идентичны стандартным грамматикам EBNF. [Вот действительно хорошее справочное руководство по пониманию грамматик ANTLR3] (http://www.antlr.org/wiki/display/ANTLR3/Quick+Starter+on+Parser+Grammars+-+No+Past+Experience+Required) – RectangleEquals

ответ

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 
     ... 

и так далее.

Не мелочный процесс, но не исключение.

+0

ANTLR 4 (http://antlr.org) позволяет левую рекурсию.Под обложками он выполняет необходимый рефакторинг грамматики перед созданием парсера вертикального спуска. – rtenhove

1

Вы запросили какие-либо советы, но ваш вопрос странно специфичен для Antlr 3.5. У вас есть требование использовать Antlr 3.5? Это поможет узнать, что вы будете использовать грамматику для: простой проверки синтаксиса или полнотекстового переводчика?

Если вы можете использовать Antlr 4, вам следует. Он обрабатывает левые факторизованные правила лучше, чем Antlr 3, и, поскольку кажется, что вы просто изучаете Antlr, Antlr 4 IMO будет легче подобрать. Если вам действительно нужен AST, то перейдите с Antlr 3

К сожалению, автоматическое средство преобразования в лучшем случае даст вам плохую отправную точку для разработки вашей грамматики.

Как где/как начать, лучше всего было бы посоветовать, чтобы получить копию грамматики Java (java.g для Antlr 3.5 или java.g4 для Antlr 4) использовать в качестве рабочего примера - Джесс, кажется, достаточно похоже, что java-грамматика должна дать вам четкое представление о том, как действовать.

+0

Прошу прощения, я должен был указать. Я переопределяю язык, чтобы быть более похожим на C/C++, и для этого мне сначала нужно было бы разобрать оригинальный язык Jass. Затем я создам парсер и лексер для собственного языка (на основе C), поместите оба синтаксических анализатора в одну и ту же библиотеку C++, а затем свяжу эту библиотеку с приложением консольного компилятора, способным интерпретировать мой язык на исходном языке сценариев Jass , изобретенный Blizzard Entertainment. Сам Джасс имеет A TON для улучшения, и я хочу заполнить эти пробелы по своему вкусу. – RectangleEquals

+0

Я бы использовал Antlr 4, но я читал, что теперь он предназначен только для разработки на Java ... И я бы предпочёл не испытывать проблемы с переустановкой eclipse только с единственной целью использования Antlr. Antlr 3.5, с другой стороны, имеет встроенный генератор С и является самой последней версией, используемой в ANTLRWorks 1.5, инструменте, который я бы предпочел не иметь. – RectangleEquals

+0

Пожалуйста, не обращайте внимания на мой предыдущий комментарий. Как оказалось, недавно они разработали ANTLRWorks2 ([link] (http://tunnelvisionlabs.com/products/demo/antlrworks)), который использует ANTLR4. Он по-прежнему ориентирован только на среду разработки java, но на сайте указано, что они работают на C++ ... Поэтому я предполагаю, что буду следить за этим, и между тем, полагаю, я мог бы иметь дело с использованием eclipse. Возможно, даже просто создайте переводчика, если я смогу сделать это так далеко. – RectangleEquals

1

Языки описания грамматики действительно маленькие. У грамматик для них есть только около дюжины правил.

Что вы могли бы сделать (что-то, что я сделал) использовать ANTLR для написания грамматики для нотации EBNF и использовать ее для перевода того, что у вас есть в грамматике ANTLR.

Это должен быть день работы, или два не более.

+0

Вы имеете в виду, создайте парсер, который преобразует EBNF в ANTLR? Если бы я мог это сделать, то, вероятно, мне бы не пришлось публиковать этот вопрос для начала. Однако, если вы уже создали такой инструмент, не могли бы вы поделиться им здесь? – RectangleEquals

+0

Я уже делал это, но мой аромат EBNF отличался от вашего, и с тех пор я перешел из ANTLR в Grako. Поверьте мне, это будет день работы или около того, а затем вы можете исправить это, чтобы сохранить его, или вы можете выбросить его после того, как он произведет необходимый вам результат. – Apalala

+1

Думаю, вам здесь не хватает места (или, может быть, я) ... Если бы я понял, как делать то, что вы предлагаете, то ** мне не нужно было бы задавать вопрос о том, как это сделать **. Я новичок в ANTLR, поэтому я пока не полностью понимаю различия между EBNF и ANTLR грамматикой. – RectangleEquals

Смежные вопросы