M.Sc.
Falco NogatzLehrstuhl für Informatik I
falco.nogatz@uni-wuerzburg.de
Raum E32
Termin nach Absprache
Falco Nogatz
University of Würzburg
M.Sc.
Falco NogatzLehrstuhl für Informatik I
falco.nogatz@uni-wuerzburg.de
Raum E32
Termin nach Absprache
More feasible is a source-to-source compiler similar to JavaScript code minification. (...) Writing such a conversion has been discussed several times, but so far never found the funding and interest to really do it.
variable token (* 6.4.3 *) = anonymous variable (* 6.4.3 *) | named variable (* 6.4.3 *) ; anonymous variable (* 6.4.3 *) = variable indicator char (* 6.4.3 *) ; named variable (* 6.4.3 *) = variable indicator char (* 6.4.3 *), alphanumeric char (* 6.5.2 *), { alphanumeric char (* 6.5.2 *) } | capital letter char (* 6.5.2 *), { alphanumeric char (* 6.5.2 *) } ; variable indicator char (* 6.4.3 *) = underscore char (* 6.5.2 *) ;
variable_token(V) --> anonymous_variable(V) | named_variable(V) anonymous_variable(['_']) --> "_" underscore named_variable(['_', A | S]) --> "_", alpa_numeric_char(A), alpha_num_seq_char(S) named_variable([C | S]) --> capital_letter_char(C), alpha_num_seq_char(S)
var tokenize = (function() { var rules = { whitespace: /^\s*(?:(?:%.*)|(?:\/\*(?:\n|\r|.)*?\*\/)|(?:\s+))\s*/, variable: /^(?:[A-Z_][a-zA-Z0-9_]*)/, point: /^\./, compound: /^((,|;|[a-z][0-9a-zA-Z_]*|[#\$\&\*\+-\.\/\:<=>\?@\^\~\\]+|'(?:[^']*?(?:\\(?:x?\d+)?\\)*(?:'')*(?:\\')*)*')\()/, atom: /^(,|;|[a-z][0-9a-zA-Z_]*|[#\$\&\*\+-\.\/\:<=>\?@\^\~\\]+|'(?:[^']*?(?:\\(?:x?\d+)?\\)*(?:'')*(?:\\')*)*')/, number: /^(?:0o[0-7]+|0x[0-9a-f]+|0b[01]+|0'(?:''|\\[abfnrtv\\'"`]|\\x?\d+\\|.)|\d+(?:\.\d+(?:e[+-]?\d+)?)?)/i, string: /^(?:"([^"]|""|\\")*"|`([^`]|``|\\`)*`)/, l_brace: /^(?:\[)/, r_brace: /^(?:\])/, l_bracket: /^(?:\{)/, r_bracket: /^(?:\})/, bar: /^(?:\|)/, l_paren: /^(?:\()/, r_paren: /^(?:\))/, cut: /^(?:\!)/, error: /^./ }; ... })();
Rule = name:RuleName? rule:RuleWithoutName RuleWithoutName = PropagationRule / SimplificationRule / SimpagationRule PropagationRule = headConstraints:Constraints __ "==>" __ guard:Guard? bodyConstraints:Body
A token shall not be followed by characters such that concatenating the characters of the token with these characters forms a valid token as specified by the above Syntax.
head//0
:head --> body.
head(In, Out) :- body(In, Out).
phrase/3
:?- phrase(DCGBody,In,Rest).
as
as --> []. as --> [a], as.
as(A, A). as([a|A], B) :- as(A, B).
?- phrase(as, Ls, []). Ls = [] ; Ls = [a] ; Ls = [a, a] ; ...
first --> body. second, [push] --> body.
first(In, Out) :- body(In, Out). second(In, [push|Out]) :- body(In, Out).
phrase/3
:?- phrase(second,In,[push|Rest]).
as
as, [0] --> []. as, [N] --> [a], as, [M], { N is M+1 }.
phrase/3
:?- phrase(as,[a,a,a],[Count|Rest]). Count = 0, Rest = [a, a, a] ; Count = 1, Rest = [a, a] ; Count = 2, Rest = [a] ; Count = 3, Rest = [] .
/* 6.4.3 Variables */ variable_token --> % 6.4.3 anonymous_variable % 6.4.3 | named_variable. % 6.4.3 anonymous_variable --> % 6.4.3 variable_indicator_char. % 6.4.3 named_variable --> % 6.4.3 variable_indicator_char % 6.4.3 , alphanumeric_char % 6.5.2 , *alphanumeric_char. % 6.5.2 named_variable --> % 6.4.3 capital_letter_char % 6.5.2 , *alphanumeric_char. % 6.5.2 variable_indicator_char --> % 6.4.3 underscore_char. % 6.5.2
?
and *
%% op `?` to denote optional occurence :- op(800, fy, ?). ?_ --> []. ?X --> X. %% op `*` to denote any number of occurences :- op(800, fy, *). *_ --> []. *X --> X, *X.
phrase/3
?- phrase(variable_token, ['A'], []). true. ?- phrase(variable_token, ['a'], []). false. ?- phrase(variable_token, ['_','a'], Rest). Rest = [a] ; Rest = [] .
%% "A token shall not be followed by characters such that %% concatenating the characters of the token with these %% characters forms a valid token as specified by the above %% Syntax." (6.4) token(In, Out) :- token_(In, Out), ( % empty rest list Out = [] ; Out = [_One_More_Element|Rests], % consuming one element does not succeed \+ token_(In, Rests) ).
term_expansion((H --> [T]), Expanded) :- Res =.. [H, T], % Res = H(T) dcg_translate_rule((H, [Res] --> [T]), Expanded).
underscore_char --> ['_'].
is expanded to
underscore_char, [underscore_char('_')] --> ['_'].
phrase/3
?- phrase(variable_token, ['A'], [T]). T = variable_token(named_variable([capital_letter_char('A')]))
variable_token --> % 6.4.3 anonymous_variable % 6.4.3 | named_variable. % 6.4.3 anonymous_variable --> % 6.4.3 variable_indicator_char. % 6.4.3 named_variable --> % 6.4.3 variable_indicator_char % 6.4.3 , alphanumeric_char % 6.5.2 , *alphanumeric_char. % 6.5.2 named_variable --> % 6.4.3 capital_letter_char % 6.5.2 , *alphanumeric_char. % 6.5.2 variable_indicator_char --> % 6.4.3 underscore_char. % 6.5.2
phrase/3
(cont.)
?- phrase(variable_token, ['A'], [T]).
T = variable_token(named_variable([capital_letter_char('A')]))
?- phrase(variable_token, ['a'], [T]).
false.
?- phrase(variable_token, ['_','a'], [T|Rest]).
T = variable_token(anonymous_variable(
variable_indicator_char(underscore_char('_')))),
Rest = [a] ;
T = variable_token(named_variable([
variable_indicator_char(underscore_char('_')),
alphanumeric_char(alpha_char(letter_char(small_letter_char(a))))
])),
Rest = [] .
fy
prefix operator:
term(P_o, Operator_Table) --> op(Op) , term(P_i) , { member(op(Op, Spec, Prec), Operator_Table), Spec = fy, P_i #=< Prec, % note the # for library(clpfd) Prec #=< P_o }.
library(tap)
SWI-Prolog pack by Michael Hendricks
swipl -q -g main -t halt -s test/test.pl
swipl -q -g 'main,halt(0)' -t 'halt(1)' -s test/test.pl
TAP version 13
1..24
ok 1 - [integer_token +] 123
ok 2 - [integer_token +] 00123
ok 3 - [integer_token -] 12 34
ok 4 - [integer_token -] 12\n34
ok 5 - [integer_token -] a
ok 6 - [integer_token -] 1.2
ok 7 - [float_number_token +] 1.2
ok 8 - [float_number_token -] 1. 2
ok 9 - [float_number_token -] 1.2.3
ok 10 - [float_number_token +] 1.2e3
ok 11 - [float_number_token +] 1.2E3
...
library(tap)
library(tap)
specifies tests as Prolog rules, get expanded using term expansion
%% test/parser/number.pl
integer_token('123'):
integer_token(
integer_constant(
[ decimal_digit_char('1'),
decimal_digit_char('2'),
decimal_digit_char('3') ])).
% integers are allowed to start with zeroes
integer_token('00123'): true.
% no space in between
integer_token('12 34'): fail.
?- ask(falco, +Question, -Answer).
This presentation is licensed under the
Creative Commons Attribution 4.0 International
license.
University of Würzburg
Chair for Computer Science I
falco.nogatz@uni-wuerzburg.de
http://uni-wuerzburg.de/?nogatz