Разбор блока кода с выражением EBNF - PullRequest
2 голосов
/ 09 сентября 2010

Я использую CocoR для создания java-подобного сканера / анализатора:
У меня возникают некоторые проблемы при создании выражения EBNF для соответствия кодовому блоку:

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

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

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

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

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

Любой намек?

Редактировать:

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} "&>".

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

Ответы [ 2 ]

1 голос
/ 02 марта 2011

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

Несколько способов сделать это:

Определить токены для <& и &>, чтобы лексер знал о них.

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

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

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

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

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

HTH

0 голосов
/ 09 сентября 2010

Вы можете расширить ЛЮБОЙ термин для включения <&, &> и другого нетерминала (назовите его ANY_WITHIN_BLOCK скажем).

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

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

И тогда значение {ЛЮБОЙ} не изменится, если оно вам действительно понадобится позже.

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

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

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

Вы сказали, что этот язык немного похож на Java, поэтому позвольте мне показать вам первые строки, которые я напишу какпервый проект, чтобы описать его грамматикуr (в псевдокоде, извините.На самом деле это как 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 */

И в то же время, когда вы делаете все это, выясняйте ваши немедленные комбинации токенов, как, например, определение «числа» какfloat или int, а затем создание правил для добавления / вычитания / и т.д.их.

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

...