2010-09-09 3 views
2

Я использую Cocor для создания Java-подобный сканер/анализатор:
У меня возникли некоторые проблемы в создании выражения EBNF соответствовать кодоблок:Синтаксический кодовый блок с выражением EBNF

Я предполагаю, кодовый блок окружен два известных лексемами: < & и &> пример:

public method(int a, int b) <& 
various code 
&> 

Если я определяю нетерминальный символ

codeblock = "<&" {ANY} "&>" 

Если код внутри двух символов содержит символ '<', сгенерированный компилятор не будет обрабатывать его, что даст синтаксическую ошибку.

Подсказка?

Edit:

COMPILER JavaLike 
CHARACTERS 

nonZeroDigit = "123456789". 
digit   = '0' + nonZeroDigit . 
letter  = 'A' .. 'Z' + 'a' .. 'z' + '_' + '$'. 

TOKENS 
ident = letter { letter | digit }. 

PRODUCTIONS 
JavaLike = {ClassDeclaration}. 
ClassDeclaration ="class" ident ["extends" ident] "{" {VarDeclaration} {MethodDeclaration }"}" . 
MethodDeclaration ="public" Type ident "("ParamList")" CodeBlock. 
Codeblock = "<&" {ANY} "&>". 

я опустил некоторые спектакли для простоты.
Это моя реальная реализация грамматики. Основная ошибка заключается в том, что она терпит неудачу, если код в блоке содержит один из символов '>' или '&'.

ответ

0

Вы можете добавить ЛЮБОЙ термин, чтобы включить <&, &> и еще один нетерминал (назовите это ANY_WITHIN_BLOCK say).

Тогда вы просто использовать

ANY = "<&" | {ANY_WITHIN_BLOCK} | "&>" 
codeblock = "<&" {ANY_WITHIN_BLOCK} "&>" 

И тогда смысл {ANY} не изменится, если вам действительно нужно это позже.

Хорошо, я ничего не знал о CocoR и дал вам бесполезный ответ, так что давайте попробуем еще раз.

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

Когда я написал CFG для одного языка, который я пытался создать, я в конечном итоге использовал своего рода подход «Встреча в середине»: я написал структуру верхнего уровня И немедленную низкоуровневую структуру, прежде всего, чтобы они встречались на среднем уровне (примерно на уровне условностей и потока управления, я думаю).

Вы сказали, что этот язык немного похож на Java, поэтому позвольте мне просто показать вам первые строки, которые я бы написал в качестве первого черновика, чтобы описать его грамматику (в псевдокоде, извините, на самом деле это похоже на yacc/bison. Я использую свои скобки вместо в Java):

/* High-level stuff */ 

program: classes 

classes: main-class inner-classes 

inner-classes: inner-classes inner-class 
      | /* empty */ 

main-class: class-modifier "class" identifier class-block 

inner-class: "class" identifier class-block 

class-block: "<&" class-decls "&>" 

class-decls: field-decl 
      | method 

method: method-signature method-block 

method-block: "<&" statements "&>" 

statements: statements statement 
      | /* empty */ 

class-modifier: "public" 
       | "private" 

identifier: /* well, you know */ 

и в то же время, как вы делаете все, что фигурирующие ваши непосредственные комбинации маркеров, как, например, определение «номер» в качестве поплавка или междунар и затем создайте правила для добавления/вычитания/etc. их.

Я не знаю, каков ваш подход до сих пор, но вы определенно хотите убедиться, что вы тщательно определяете все и используете новые правила, когда хотите определенную структуру. Не смешайтесь с созданием индивидуальных правил, но никогда не бойтесь создавать новое правило, если это поможет вам лучше организовать свои мысли.

+0

как бы вы определили ANY_WITHIN_BLOCK? – nick2k3

+0

Как вы определяете ЛЮБОЕ? –

+0

ANY - это «веселый» токен в CocoR: он соответствует каждому знаку. – nick2k3

1

Ник, опоздал на вечеринку здесь ...

ряд способов сделать это:

Определение маркеров для <& и &> так лексер знает о них.

Вы можете быть в состоянии использовать директиву КОММЕНТАРИИ

КОММЕНТАРИИ ОТ <& К &> - цитирует ожидает CoCo.

Или сделайте взломать NextToken() в файле scanner.frame. Есть ли что-то вроде этого (псевдо-код):

if (Peek() == CODE_START) 
{ 
    while (NextToken() != CODE_END) 
    { 
     // eat tokens 
    } 
} 

Или может переопределить метод Read() в буфере и есть на самом низком уровне.

HTH

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