2015-05-13 6 views
0

В настоящее время я работаю над грамматикой, которая должна позволить мне определять локальные и глобальные массивы или переменные.
Местные начинают с подчеркивания, и это единственное отличие в именах. Специальных ключевых слов не существует, чтобы определить, является ли он локальным или глобальным, и нет ключевых слов, указывающих, является ли объявление массивом или переменной.
Переменная может быть некоторыми нормальными типами и ссылкой на другую переменную (локальную или глобальную), а массив можно либо обрезать со стандартными фигурными скобками, либо как ссылку на существующий массив.Как переписать эту грамматику, чтобы она не была неоднозначной больше

Проблема в том, что Xtext не может разделяться, если «имя = ссылка» является переменной или массивом.
Это моя существующая грамматика:

grammar org.declarations.dec.Dec with org.eclipse.xtext.common.Terminals 
import "http://www.eclipse.org/emf/2002/Ecore" as ecore 

generate dec "http://www.declarations.org/dec/Dec" 

Model: 
delarations+=(Declaration)* 
; 

Declaration: 
Variable ";" | Array ";" 
; 

Variable: 
    LocalVar 
    | GlobalVar 
; 

    LocalVar: 
     name=LOCALNAME "=" variableContent=VarContent 
    ; 

    GlobalVar: 
     name=GLOBALNAME "=" variableContent=VarContent 
    ; 

     VarContent: 
      stringContent=STRING 
      | IntContent=INT 
      | localRef=[LocalVar|LOCALNAME] 
      | globalRef=[GlobalVar|GLOBALNAME] 
     ; 

Array: 
    LocalArray 
    |GlobalArray 
; 

    LocalArray: 
     name=LOCALNAME "=" content=ArrayLiteral 
    ; 

    GlobalArray: 
     name=GLOBALNAME "=" content=ArrayLiteral 
    ; 

     ArrayLiteral: 
      "[" (c1=ArrayContent ("," c2+=ArrayContent)*)? "]" 
      | localRef=[LocalArray|LOCALNAME] 
      | globalRef=[GlobalArray|GLOBALNAME] 
     ; 

      ArrayContent: 
       varContent=VarContent 
       | localRef=[LocalArray|LOCALNAME] 
       | globalRef=[GlobalArray|GLOBALNAME] 
      ; 



terminal LOCALNAME: 
    "_" ('a'..'z'|'A'..'Z') ('a'..'z'|'A'..'Z'|'_'|'0'..'9')* 
; 
terminal GLOBALNAME: 
    ('a'..'z'|'A'..'Z') ('a'..'z'|'A'..'Z'|'_'|'0'..'9')* 
; 

код я хочу признать, например:

_localVar1 = "Test"; 
globalVar1 = _localVar1; 

globalArray = ["hello",globalVar1]; 
nextArray = globalArray; 
anotherArray = [globalArray, nextArray]; 

ли кто-нибудь идея, как решить эту проблему?

Привет Krzmbrzl

+0

это невозможно без потери семантики или предпочитают одну конструкцию '' 'хххх = yyyy'''or' '' _xxx = _yyy''' оба переменных и массивов. почему вы вообще их отличаете? почему бы не ввести VarContent, который является массивом и дампом Array для dev null –

+0

ну, я хотел бы различать их, потому что я хочу использовать их для синтаксиса команд, принимающих переменную или массив ... Что именно вы имеете в виду с «дампом» Массивы для dev null "? – Raven

+0

привет, вы должны разделить систему типа и ast. таким образом, имеет ast, который имеет только переменные и систему типов, которая проверяет, что только правильные типы используются в правильных местах (так же, как это делает java). поэтому вы должны выбросить массив и иметь только вары –

ответ

1

Как на мой вопрос ответил только через комментарии, которые я напишу ответ, так что вопрос не будет в безответной разделе. Я нашел решение благодаря Кристиану Дитриху:

Решение должно было позволить анализу игнорировать, является ли объявление переменной или массивом, а также игнорировать, является ли объявление локальным или глобальным. Полученная грамматика выглядит следующим образом:

Model: 
elements += Code* 
; 

Code: 
dec=Declaration ";" 
; 

Declaration: 
    name = ID "=" decCon=DecContent 
; 

    DecContent: 
     singleContent=VarContent (op+=OPERATOR nextCon+=VarContent)* 
    ; 

     VarContent: 
      num = NUMBER 
      | string = STRING 
      | reference = [Declaration] 
      | "+"? arrayContent=ArrayLiteral 
     ; 

      ArrayLiteral: 
       con = "[" (content = VarContent ("," nextContent += VarContent)*)? "]" 
      ; 

Выяснение ли декларация является переменной, массивом, локальным или gloabal является задачей валидатора.
Правило здесь: делать как можно меньше с помощью синтаксического анализатора и как можно больше с помощью валидатора.

Надеюсь, что это может помочь вам, если у вас есть аналогичная проблема.

Привет Krzmbrzl