2015-02-24 2 views
1

Я пытаюсь разобрать текстовый файл через javaCC. Файл состоит из нескольких предложений, разделенных символом новой строки. Каждая строка может содержать любую последовательность «a» и «b», но должна заканчиваться «a», за которой следует «b» перед новой строкой. JavaCC не анализирует то же самое и потребляет терминальные токены a и b как часть дополнительной серии.javaCC Parsing Limitation

Это должен быть успешно проанализирован с помощью JavaCC:

aa ab aab 
aab 

Файла JJT выглядит следующим образом:

options { 
STATIC = false ; 
FORCE_LA_CHECK = true; 
LOOKAHEAD = 20000; 
DEBUG_PARSER = true; 
DEBUG_LOOKAHEAD = true; 
OTHER_AMBIGUITY_CHECK = 3; 
} 

PARSER_BEGIN(Test) 
class Test { 
public static void main(String[] args) 
throws ParseException { 
    Test act = new Test (System.in); 
    SimpleNode root = act.Start() ; 
    root.dump (" "); 
    //ystem.out.println("Total = "+val); 
} 
}PARSER_END(Test) 

TOKEN_MGR_DECLS : 
{ 
    int stringSize; 
} 

SKIP : { < WS : " " > } 
SKIP : {"\t" | "\r" | "\uFFFF" | "\u201a" | "\u00c4" | "\u00ee" | "\u00fa" | "\u00f9" | "\u00ec" | "\u2013" } 

TOKEN [IGNORE_CASE] : 
{ 
    < A : "a" > 
| < B : "b" > 
| < NEWLINE : (("\n")+) > 
} 


SimpleNode Start() throws NumberFormatException : 
{ 
    int i ; 
    int value=0 ; 
} { 
chapter() 
{ 
    return jjtThis; } 
} 

void chapter() : 
{ } { 
    (LOOKAHEAD (part_sentence()) part_sentence())+ (newline())? <EOF> 
} 
void part_sentence() : 
{ } { 
    <NEWLINE> (a() | b())+ a() b() 
} 
void a() : 
{ } { 
    <A> 
} 
void b() : 
{ } { 
    <B> 
} 
void newline() throws NumberFormatException : 
{ }{ 
    <NEWLINE> 
    { System.out.print ("N# "); } 
} 

Это может быть выяснено, что нетерминалы а() и б() не может быть заменен токеном; они принимаются как «a» и «b» только для простоты. Кроме того, «NEWLINE» не может быть перенесено в конец нетерминальной «part_sentence» из-за других ограничений.

Я застрял в этой проблеме за последние 4 дня. Моя последняя надежда была семантическим разбором - LOOKAHEAD ({! (GetToken (1) .kind == a() & & getToken (2) .kind == b() & & getToken (3) .kind == newline()} !), но не может получить дескриптор нетерминалов Любая помощь будет высоко оценил

ответ

0

[Примечание:. вы говорите любую последовательность элементов а и Ь, которые поступают с «AB», но ваш код использует + не *. Я предполагаю, что вы действительно означали любую последовательность, которая заканчивается на «ab», включая последовательность «ab». Конечная нота.]

Вам нужно выйти из цикла на основе взгляда. хочу сделать это

(LOOKAHEAD(x) 
    (a() | b()) 
)* 
a() b() <NEWLINE> 

где x говорит, что если следующие элементы ввода не совпадаютa() b() <NEWLINE>. К сожалению, нет способа сказать «не совпадать», используя синтаксический взгляд вперед. Хитрость заключается в том, чтобы заменить петлю рекурсией.

void oneLine() : {} { 
    LOOKAHEAD(a() b() <NEWLINE>) 
    a() b() <NEWLINE> 
| 
    a() oneLine() 
| 
    b() oneLine() 
} 

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

void oneLine() : {} { <NEWLINE> oneLinePrime() } 

void oneLinePrime() : {} { 
    LOOKAHEAD(a() b() <NEWLINE>) 
    a() b() 
| 
    a() oneLinePrime() 
| 
    b() oneLinePrime() 
} 
+0

Теодор, я впечатлен, чтобы увидеть глубину вашего ответа вместе с болями, которые вы могли предпринять, чтобы написать то же самое. Вы ответили на мой вопрос. Постарайтесь реализовать то же самое в моей относительно сложной грамматике и обновить результат. Спасибо (BTW; это был мой первый пост в stackoverflow (или любой другой сайт, если на то пошло) –

+0

Добро пожаловать в StackOverflow. –

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

  • Нет связанных вопросов^_^