2016-03-17 2 views
0

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

%TokenList=[int, add, '(', int, a, ',', int, b, ')']. 


lexer([H|TokenList],Output,[Output|X2]):- 
    lexer_test(H,Output),lexer(TokenList,Output,X2). 

lexer_test(H,Output):- 
    (
    H = '\'int\'' -> Output = 'TYPE_INT' 
    ;(H = '\'bool\'' -> Output='TYPE_BOOL' 
    ;(H = '\',\'' -> Output='COMMA' 
    ;(H = '\'=\'' -> Output='ASSIGN' 
    ;(H = '\'let\'' -> Output='LET' 
    ;(H = '\'in\'' -> Output='LET_IN' 
    ;(H = '\'if\'' -> Output='COND_IF' 
    ;(H = '\'then\'' -> Output='COND_THEN' 
    ;(H = '\'else\'' -> Output='COND_ELSE' 
    ;(H = '\'==\'' -> Output='LOGIC_EQ' 
    ;(H = '\'!=\'' -> Output='LOGIC_NOT_EQ' 
    ;(H = '\'>\'' -> Output='LOGIC_GT' 
    ;(H = '\'>=\'' -> Output='LOGIC_GTEQ' 
    ;(H = '\'+\'' -> Output='ARITH_ADD' 
    ;(H = '\'-\'' -> Output='ARITH_SUB' 
    ;(H = '\'(\'' -> Output='OPEN_P' 
    ;(H = '\')\'' -> Output='CLOSE_P' 
    ;(H = '\'0\'' -> Output='INTEGER' 
    ;(H = '\'1\'' -> Output='INTEGER' 
    ;(H = '\'2\'' -> Output='INTEGER' 
    ;(H = '\'3\'' -> Output='INTEGER' 
    ;(H = '\'4\'' -> Output='INTEGER' 
    ;(H = '\'5\'' -> Output='INTEGER' 
    ;(H = '\'6\'' -> Output='INTEGER' 
    ;(H = '\'7\'' -> Output='INTEGER' 
    ;(H = '\'8\'' -> Output='INTEGER' 
    ;(H = '\'9\'' -> Output='INTEGER' 
    ;(Output='IDENTIFIER' 
    )))))))))))))))))))))))))))). 

Не беспокойтесь о второй функции lexer_test. Я могу это исправить. Но я действительно не знаю, почему у меня нет выходного списка. И если я могу сделать lexer/2 вместо lexer/3, это было бы здорово. И если вы могли бы предложить некоторые хорошие чтения для изучения пролога, пожалуйста, дайте мне знать. Благодарю.

+3

Я знаю, что вы сказали, не беспокоиться о 'lexer_test' (который является * предикат * не * функция *), но я могу» t help commenting ... :) Что вы хотите здесь, это набор фактов: 'lexer_id (int, 'TYPE_INT').' и 'lexer_id (bool, 'TYPE_BOOL').' и т. д., а не большой набор «последствий» ». Однако вы можете использовать предикат для вашего catch-all в идентификаторе, например 'lexer_test (H, Output): - (lexer_id (H, Output) -> true; Output = 'IDENTIFIER') .' – lurker

+3

.. и то все эти дополнительные кавычки '' 1'' вместо '' \ '1 \' '', вероятно, достаточно хороши – false

ответ

1

На данный момент, вы не указываете условие завершения:

lexer([H|TokenList],Output,[Output|X2]):- 
    lexer_test(H,Output),lexer(TokenList,Output,X2). 

Лексер продолжает называть себя (рекурсия), но у вас нет другого пункт указан, и, таким образом, Пролог будет в конечном итоге в бесконечном цикле. Состояние, которое вы ищете:

lexer([],_,[]). 

как остановка состояние. В этом выражается условие, в котором токенлист становится пустым.

Хорошее место, чтобы начать обучение пролога (IMHO) будет: http://www.learnprolognow.org/