Skip to content

Commit

Permalink
reference solutions
Browse files Browse the repository at this point in the history
git-svn-id: https://slps.svn.sourceforge.net/svnroot/slps@703 ab42f6e0-554d-0410-b580-99e487e6eeb2
  • Loading branch information
grammarware committed Nov 9, 2009
1 parent 8b8d753 commit 46b21dc
Show file tree
Hide file tree
Showing 10 changed files with 332 additions and 8 deletions.
9 changes: 9 additions & 0 deletions topics/exercises/while2/Makefile
@@ -0,0 +1,9 @@
test:
swipl -f RunParser.pro -t "main('input.txt')"

debug:
cat input.txt
swipl -s Parser.pro

clean:
rm -rf *~
142 changes: 142 additions & 0 deletions topics/exercises/while2/Parser.pro
@@ -0,0 +1,142 @@
%% Parser for While language
% Program is a list of statements
program(S) --> statements(S).

% Non-empty list
statements(slist(H,T)) -->
statement(H),
keyword(";"),
statements(T).

% Empty list
statements(S) --> statement(S).

%% Statements
% Skip statement
statement(skip) -->
keyword("skip").

% Assign statement
statement(assign(identifier(V),E)) -->
identifier(V),
keyword(":="),
aexpression(E).

% Conditional statement
statement(ifthenelse(E,S1,S2)) -->
keyword("if"),
bexpression(E),
keyword("then"),
statement(S1),
keyword("else"),
statement(S2).

% Loop statement
statement(while(E,S)) -->
keyword("while"),
bexpression(E),
keyword("do"),
statement(S).


%% Arithmetic expressions
% Number is a an arithmetic expression
aexpression(number(N)) --> number(N).

% Variable reference is a an arithmetic expression
aexpression(identifier(V)) --> identifier(V).

% A sum of arithmetic expressions is also an arithmetic expression
aexpression(add(E1,E2)) -->
keyword("("),
aexpression(E1),
keyword("+"),
aexpression(E2),
keyword(")").

% Same with subtraction
aexpression(sub(E1,E2)) -->
keyword("("),
aexpression(E1),
keyword("-"),
aexpression(E2),
keyword(")").

% ...and multiplication
aexpression(mul(E1,E2)) -->
keyword("("),
aexpression(E1),
keyword("*"),
aexpression(E2),
keyword(")").


%% Boolean expressions
% Boolean primitives are boolean expressions
bexpression(true) --> keyword("true").
bexpression(false) --> keyword("false").

% Comparison is a boolean expression: equality
bexpression(equals(E1,E2)) -->
aexpression(E1),
keyword("="),
aexpression(E2).

% Comparison is a boolean expression: less than or equal to
bexpression(lte(E1,E2)) -->
aexpression(E1),
keyword("≤"),
aexpression(E2).

% Negation is a boolean expression
bexpression(not(E)) -->
keyword("¬"),
bexpression(E).

% Disjunction of boolean expressions is also a boolean expression
bexpression(and(E1,E2)) -->
keyword("("),
bexpression(E1),
keyword("^"),
bexpression(E2),
keyword(")").


%% Low-level details
% Dealing with layout
layout --> [0' ], layout. %' space
layout --> [0' ], layout. %' tab
layout --> [10], layout. % newline
layout --> [].

% Keywords are space-consuming strings
keyword(X) -->
layout,
string(X).

% Bare strings
string([],X,X).
string([H|T1],[H|T2],X) :- string(T1,T2,X).

% Numbers are space-consuming digits
number(N) -->
layout,
digit(H), digits(T),
{ number_chars(N,[H|T]) }.

% Bare digits
digits([H|T]) --> digit(H), digits(T).
digits([]) --> [].
digit(H,[H|T],T) :- H >= 0'0, H =< 0'9.

% Identifiers are space-consuming letters
identifier(V) -->
layout,
letter(H), letters(T),
{ atom_chars(V,[H|T]) }.

% Bare letters
letters([H|T]) --> letter(H), letters(T).
letters([]) --> [].
letter(H,[H|T],T) :- H >= 0'a, H =< 0'z.

17 changes: 17 additions & 0 deletions topics/exercises/while2/RunParser.pro
@@ -0,0 +1,17 @@
:- ['Parser.pro'].

main(File) :-
parseFile(File,program,S),
write(S),nl.

parseFile(File,P,R) :-
open(File,read,Stream,[]),
read_stream_to_codes(Stream, Contents),
close(Stream),
apply(P,[R,Contents,Rest]),
eof(Rest,_).

eof([],[]).
eof([0' |T],R) :- eof(T,R). %'
eof([10|T],R) :- eof(T,R).

7 changes: 7 additions & 0 deletions topics/exercises/while2/input.txt
@@ -0,0 +1,7 @@
if ¬x ≤ 0
then
y:=((2+x)-y)
else
while z=0 do
z:=2;
skip
60 changes: 52 additions & 8 deletions topics/exercises/while3/Parser.pro
@@ -1,3 +1,4 @@
%% Parser for While language
% Program is a list of statements
program(S) --> statements(S).

Expand All @@ -10,7 +11,7 @@ statements(slist(H,T)) -->
% Empty list
statements(S) --> statement(S).

% Statements
%% Statements
% Skip statement
statement(skip) -->
keyword("skip").
Expand All @@ -30,7 +31,15 @@ statement(ifthenelse(E,S1,S2)) -->
keyword("else"),
statement(S2).

% Expressions
% Loop statement
statement(while(E,S)) -->
keyword("while"),
bexpression(E),
keyword("do"),
statement(S).


%% Arithmetic expressions
% Number is a an arithmetic expression
aexpression(number(N)) --> number(N).

Expand All @@ -45,6 +54,24 @@ aexpression(add(E1,E2)) -->
aexpression(E2),
keyword(")").

% Same with subtraction
aexpression(sub(E1,E2)) -->
keyword("("),
aexpression(E1),
keyword("-"),
aexpression(E2),
keyword(")").

% ...and multiplication
aexpression(mul(E1,E2)) -->
keyword("("),
aexpression(E1),
keyword("*"),
aexpression(E2),
keyword(")").


%% Boolean expressions
% Boolean primitives are boolean expressions
bexpression(true) --> keyword("true").
bexpression(false) --> keyword("false").
Expand All @@ -61,13 +88,30 @@ bexpression(lte(E1,E2)) -->
keyword("≤"),
aexpression(E2).

% Dealing with spaces
spaces --> [0' ], spaces. %'
spaces --> [].
% Negation is a boolean expression
bexpression(not(E)) -->
keyword("¬"),
bexpression(E).

% Disjunction of boolean expressions is also a boolean expression
bexpression(and(E1,E2)) -->
keyword("("),
bexpression(E1),
keyword("^"),
bexpression(E2),
keyword(")").


%% Low-level details
% Dealing with layout
layout --> [0' ], layout. %' space
layout --> [0' ], layout. %' tab
layout --> [10], layout. % newline
layout --> [].

% Keywords are space-consuming strings
keyword(X) -->
spaces,
layout,
string(X).

% Bare strings
Expand All @@ -76,7 +120,7 @@ string([H|T1],[H|T2],X) :- string(T1,T2,X).

% Numbers are space-consuming digits
number(N) -->
spaces,
layout,
digit(H), digits(T),
{ number_chars(N,[H|T]) }.

Expand All @@ -87,7 +131,7 @@ digit(H,[H|T],T) :- H >= 0'0, H =< 0'9.

% Identifiers are space-consuming letters
identifier(V) -->
spaces,
layout,
letter(H), letters(T),
{ atom_chars(V,[H|T]) }.

Expand Down
12 changes: 12 additions & 0 deletions topics/exercises/xml2/Makefile
@@ -0,0 +1,12 @@
test:
swipl -f RunParser.pro -t "main('input.txt')"

fail:
swipl -f RunParser.pro -t "main('bad.txt')"

debug:
cat input.txt
swipl -s Parser.pro

clean:
rm -rf *~
66 changes: 66 additions & 0 deletions topics/exercises/xml2/Parser.pro
@@ -0,0 +1,66 @@
% A root tree is a regular tree with an opening and closing tags and a forest in between
tree(tree(N,AL,TL)) -->
layout,
string("<"),
name(N),
attrs(AL,_),
string(">"),
trees(TL),
string("</"),
name(N),
string(">"),
layout.

% A non-empty forest
trees([H|T]) -->
tree(H),
trees(T).

% An empty forest
trees([]) --> [].

% Attribute list
attrs([H|T],[N|U]) -->
layout,
attr(H),
attrs(T,U),
{
H = [N,_],
not(member(N,U))
}.
attrs([],[]) --> [].

% Attribute
attr([N,V]) -->
name(N),
string("="),
value(V).

% Bare strings
string([],X,X).
string([H|T1],[H|T2],X) :- string(T1,T2,X).

% Consuming spaces
layout --> [0' ], layout. % space '
layout --> [0' ], layout. % tab '
layout --> [10], layout. % newline
layout --> [].

% Only lowcased tag names are allowed
name(N) -->
letter(H), letters(T),
{ atom_codes(N,[H|T]) }.

% Bare letters
letters([H|T]) --> letter(H), letters(T).
letters([]) --> [].
letter(H,[H|T],T) :- H >= 0'a, H =< 0'z.

value(V) -->
char(H), chars(T),
{ atom_codes(V,[H|T]) }.

chars([H|T]) --> char(H), chars(T).
chars([]) --> [].
char(H,[H|T],T) :- H >= 0'a, H =< 0'z.
char(H,[H|T],T) :- H >= 0'0, H =< 0'9.
19 changes: 19 additions & 0 deletions topics/exercises/xml2/RunParser.pro
@@ -0,0 +1,19 @@
:- ['Parser.pro'].

main(File)
:-
parseFile(File,tree,S),
write(S), nl.

parseFile(File,P,R)
:-
open(File,read,Stream,[]),
read_stream_to_codes(Stream, Contents),
close(Stream),
apply(P,[R,Contents,Rest]),
eof(Rest,_).

eof([],[]).
eof([0' |T],R) :- eof(T,R). %'
eof([10|T],R) :- eof(T,R).

4 changes: 4 additions & 0 deletions topics/exercises/xml2/bad.txt
@@ -0,0 +1,4 @@
<a x=4 x=5>
<b></b>
<c y=true></c>
</a>
4 changes: 4 additions & 0 deletions topics/exercises/xml2/input.txt
@@ -0,0 +1,4 @@
<a x=4>
<b></b>
<c x=2 y=true></c>
</a>

0 comments on commit 46b21dc

Please sign in to comment.