Разбор блока кода с выражением EBNF

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

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

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

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

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

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

Любой намек?

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

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 ответа

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

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

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

Вы можете использовать директиву COMMENTS

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

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

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

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

НТН

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

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

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

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

Хорошо, я ничего не знал о 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 */

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

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

Другие вопросы по тегам