Использовать 1 a float и float division
public static void main(String d[]){
double g=1f/3;
System.out.printf("%.2f",g);
}
После размышления об этом некоторое время несколько дней назад, и придумывающий ничто стоящее отправить, я возвратился к нему теперь и придумал некоторый синтаксис я скорее как, потому что это почти похоже на Python:
macro PrintMacro:
syntax:
"print", OneOrMore(Var(), name='vars')
return Printnl(vars, None)
Var()
вместо простого Var
) Передача название элементов как "ключевой параметр" к объектам, которых мы хотим название. Должно все еще быть легко найти все имена в синтаксическом анализаторе, так как это определение синтаксиса так или иначе должно быть интерпретировано в некотором роде для заполнения макро-переменной синтаксиса классов.
потребности, которые будут преобразованы для заполнения переменной синтаксиса получающегося макро-класса.
внутреннее представление синтаксиса могло также выглядеть одинаково:
class PrintMacro(Macro):
syntax = 'print', OneOrMore(Var(), name='vars')
...
внутренние классы синтаксиса как [1 110] следовали бы за этим шаблоном для разрешения подэлементов и дополнительного имени:
class MacroSyntaxElement(object):
def __init__(self, *p, name=None):
self.subelements = p
self.name = name
, Когда макрос соответствует, Вы просто собираете все объекты, которые имеют имя и передают их как ключевые параметры к функции-обработчику:
class Macro():
...
def parse(self, ...):
syntaxtree = []
nameditems = {}
# parse, however this is done
# store all elements that have a name as
# nameditems[name] = parsed_element
self.handle(syntaxtree, **nameditems)
функция-обработчик была бы затем определена как это:
class PrintMacro(Macro):
...
def handle(self, syntaxtree, vars):
return Printnl(vars, None)
я добавил syntaxtree как первый параметр, который всегда передается, таким образом, у Вас не должно было бы быть именованных объектов, если Вы просто хотите сделать очень простой материал на синтаксическом дереве.
кроме того, если Вам не нравятся декораторы, почему бы не добавить макро-тип как "базовый класс"? IfMacro
был бы затем похож на это:
macro IfMacro(MultiLine):
syntax:
Group("if", Var(), ":", Var(), name='if_')
ZeroOrMore("elif", Var(), ":", Var(), name='elifs')
Optional("else", Var(name='elseBody'))
return If(
[(cond, Stmt(body)) for keyword, cond, colon, body in [if_] + elifs],
None if elseBody is None else Stmt(elseBody)
)
И во внутреннем представлении:
class IfMacro(MultiLineMacro):
syntax = (
Group("if", Var(), ":", Var(), name='if_'),
ZeroOrMore("elif", Var(), ":", Var(), name='elifs'),
Optional("else", Var(name='elseBody'))
)
def handle(self, syntaxtree, if_=None, elifs=None, elseBody=None):
# Default parameters in case there is no such named item.
# In this case this can only happen for 'elseBody'.
return If(
[(cond, Stmt(body)) for keyword, cond, body in [if_] + elifs],
None if elseNody is None else Stmt(elseBody)
)
я думаю, что это дало бы довольно гибкую систему. Основные преимущества:
None
в обработчике Several("abc", min=3, max=5, name="a")
. Я думаю, что это могло также использоваться для добавления значений по умолчанию к дополнительным элементам как [1 114]. я не уверен в заключить в кавычки/закрыть кавычки синтаксисе с "кавычкой": и "$", но некоторый синтаксис для этого необходим, так как он делает жизнь намного легче, если Вы не должны вручную писать синтаксические деревья. Вероятно, это - хорошая идея потребовать (или просто разрешить?) круглая скобка за "$", так, чтобы можно было вставить более сложные части синтаксиса, если Вы хотите. Как [1 115].
ToMacro выглядел бы примерно так:
# macro definition
macro ToMacro(Partial):
syntax:
Var(name='start'), "to", Var(name='end'), Optional("inclusive", name='inc'), Optional("step", Var(name='step'))
if step == None:
step = quote(1)
if inclusive:
return quote:
xrange($(start), $(end)+1, $(step))
else:
return quote:
xrange($(start), $(end), $(step))
# resulting macro class
class ToMacro(PartialMacro):
syntax = Var(name='start'), "to", Var(name='end'), Optional("inclusive", name='inc'), Optional("step", Var(name='step'))
def handle(syntaxtree, start=None, end=None, inc=None, step=None):
if step is None:
step = Number(1)
if inclusive:
return ['xrange', ['(', start, [end, '+', Number(1)], step, ')']]
return ['xrange', ['(', start, end, step, ')']]
Вы должны взглянуть на MetaPython , чтобы увидеть, достигает ли он того, что вы ищете .
Вы могли бы рассмотреть взгляд на то, как Шиканье (основанный на.NET язык с синтаксисом, в основном вдохновленным Python), реализует макросы, как описано по телефону http://boo.codehaus.org/Syntactic+Macros .
Это - новый макро-синтаксис, который я придумал на основе идей Kent Fredric. Это анализирует синтаксис в список точно так же, как код анализируется.
макрос Печати:
macro PrintMacro:
syntax:
print $stmts
if not isinstance(stmts, list):
stmts = [stmts]
return Printnl(stmts, None)
, Если макрос:
@MultiLine
macro IfMacro:
syntax:
@if_ = if $cond: $body
@elifs = ZeroOrMore(elif $cond: $body)
Optional(else: $elseBody)
return If(
[(cond, Stmt(body)) for cond, body in [if_] + elifs],
elseBody != None and Stmt(elseBody) or None
)
X к Y [содержащему] [шаг Z] макрос:
@Partial
macro ToMacro:
syntax:
$start to $end Optional(inclusive) Optional(step $step)
if step == None:
step = quote 1
if inclusive:
return quote:
xrange($start, $end+1, $step)
else:
return quote:
xrange($start, $end, $step)
Кроме незначительной проблемы использования декораторов для идентификации макро-типа моей единственной реальной проблемой с этим является способ, которым можно назвать группы, например, в если случай. Я использую @name =..., но это просто сильно пахнет Perl. Я не хочу просто использовать имя =..., потому что это могло конфликтовать с макро-шаблоном для соответствия. Какие-либо идеи?
Слияние BNF
class IfMacro(Macro):
syntax: "if" expression ":" suite ("elif" expression ":" suite )* ["else" ":" suite]
def handle(self, if_, elifs, elseBody):
return If(
[(expression, Stmt(suite)) for expression, suite in [if_] + elifs],
elseBody != None and Stmt(elseBody) or None
)
Я отправляю немного плавающих идей видеть, вдохновляет ли это. Я не знаю много Python, и я не использую реальный синтаксис Python, но он ничего не бьет :p
macro PrintMacro:
syntax:
print $a
rules:
a: list(String), as vars
handle:
# do something with 'vars'
macro IfMacro:
syntax:
if $a :
$b
$c
rules:
a: 1 boolean as if_cond
b: 1 coderef as if_code
c: optional macro(ElseIf) as else_if_block
if( if_cond ):
if_code();
elsif( defined else_if_block ):
else_if_block();
[еще 113] идеи:
стиль кавычки Perl Реализации, но в Python! (это - очень плохая реализация и примечание: пробел является значительным в правиле)
macro stringQuote:
syntax:
q$open$content$close
rules:
open: anyOf('[{(/_') or anyRange('a','z') or anyRange('0','9');
content: string
close: anyOf(']})/_') or anyRange('a','z') or anyRange('0','9');
detect:
return 1 if open == '[' and close == ']'
return 1 if open == '{' and close == '}'
return 1 if open == '(' and close == ')'
return 1 if open == close
return 0
handle:
return content;
Если Вы только спрашиваете о синтаксисе (не реализация) макросов в рамках Python, то я полагаю, что ответ очевиден. Синтаксис должен тесно соответствовать тому, что Python уже имеет (т.е." def
" ключевое слово).
, Реализуете ли Вы это, поскольку одно из следующего ваше дело:
def macro largest(lst):
defmac largest(lst):
macro largest(lst):
, но я полагаю, что это должно быть точно то же как нормальная функция относительно остальных так, чтобы:
def twice_second(a,b):
glob_i = glob_i + 1
return b * 2
x = twice_second (1,7);
и
defmac twice_second(a,b):
glob_i = glob_i + 1
return b * 2
x = twice_second (1,7);
функционально эквивалентны.
способ, которым я реализовал бы это, с препроцессором (а-ля C), который был бы:
a
с __macro_second_local_a
. Несомненно будет некоторый nigglies для заботы о (как кортежи или несколько точек возврата), но Python достаточно устойчив для обработки этого, по-моему.
Так:
x = twice_second (1,7);
становится:
# These lines are the input params.
__macro_second_param_a = 1
__macro_second_param_b = 7
# These lines are the inlined macro.
glob_i = glob_i + 1
__macro_second_retval = __macro_second_param_b * 2
# Modified call to macro.
x = __macro_second_retval
Это - текущий механизм для определения синтаксиса при помощи стандартного класса Python.
макрос Печати:
class PrintMacro(Macro):
syntax = 'print', Var
def handle(self, stmts):
if not isinstance(stmts, list):
stmts = [stmts]
return Printnl(stmts, None)
макро-класс If/elif/else:
class IfMacro(MLMacro):
syntax = (
('if', Var, Var),
ZeroOrMore('elif', Var, Var),
Optional('else', Var)
)
def handle(self, if_, elifs, elseBody):
return If(
[(cond, Stmt(body)) for cond, body in [if_] + elifs],
elseBody != None and Stmt(elseBody) or None
)
X к Y [содержащему] [шаг Z] класс макроса:
class ToMacro(PartialMacro):
syntax = Var, 'to', Var, Optional('inclusive'), Optional('step', Var)
def handle(self, start, end, inclusive, step):
if inclusive:
end = ['(', end, '+', Number(1), ')']
if step == None: step = Number(1)
return ['xrange', ['(', start, end, step, ')']]
Мои проблемы с этим дизайном - то, что вещи являются очень подробными и не чувствуют pythonic ни в малейшей степени. Кроме того, отсутствие способности к цитате делает сложные макросы трудными.
Это - макро-синтаксис, который я придумал для своего надмножества Python.
макрос Печати:
macro PrintMacro:
syntax:
stmts = 'print', Var
if not isinstance(stmts, list):
stmts = [stmts]
return Printnl(stmts, None)
, Если макрос:
@MultiLine
macro IfMacro:
syntax:
if_ = 'if', Var, Var
elifs = ZeroOrMore('elif', Var, Var)
else_ = Optional('else', Var)
return If(
[(cond, Stmt(body)) for cond, body in [if_] + elifs],
elseBody != None and Stmt(elseBody) or None
)
X к Y [содержащему] [шаг Z] макрос:
@Partial
macro ToMacro:
syntax:
start = Var
'to'
end = Var
inclusive = Optional('inclusive')
step = Optional('step', Var)
if step == None:
step = quote 1
if inclusive:
return quote:
xrange($start, $end+1, $step)
else:
return quote:
xrange($start, $end, $step)
Моя основная проблема с этим - то, что блок синтаксиса неясен, особенно 'к' строке в последнем примере. Я - также не большой поклонник использования декораторов для дифференциации макро-типов.