Code Formatting（代码格式）

（以下内容，译自Category:Tutorials中的Code Formatting. 更多内容可以参看Category:Chinese. ） 本文描述用于Visual Prolog程序的编码标准，Visual Prolog系统自身也是这样写的. 用户文档中的例子也是使用这个标准. 因此，PDC也推荐用户使用这个标准.  关键字 关键字使用小写字母. 在文档中关键字用粗体无衬线字体，如Arial. 缺省颜色为暗绿色. 

constants domains facts predicates class interface ...

半关键字 Visual Prolog中对各种语法结构使用了许多记号. 这些词也都是使用小写（除了用C语言写的C调用中的惯例外）的普通无衬线字体，其颜色根据它们不同的性质分成两种：如果是表示一种选择则用海军蓝色，如果是结构词则使用暗绿色. 

erroneous failure procedure determ nondeterm multi language as stdcall c ...

下面的例子示出颜色与字体的使用：

predicates myPredicate : (string Value) procedure (i) language stdcall as "_myP"

<SPAN class=mw-headline>文字</SPAN></H2> 文字的颜色为蓝色. </P>

1 "Hello world!"

<SPAN class=mw-headline>标识符</SPAN></H2> 标识符的一般格式可以用下面的EBNF文法描述：</P>&lt;Identifier&gt; = &lt;Prefix&gt; &lt;WordGroups&gt; &lt;Suffix&gt; &lt;WordGroups&gt; = &lt;WordGroup&gt; { ‘_’ &lt;WordGroup&gt; }* &lt;WordGroup&gt; = &lt;Word&gt;+</PRE> 前缀与后缀用于表示标识符的种类，并连同每一类标识符一道处理. 除了对那些整个标识符的首字母必须小写的情况而外，单词要大写. </P> 变量都以大写字母打头，所有其它的都是小写打头. </P> 文档中除了关键字都使用衬线字体，如Times New Roman.

<H3><SPAN class=mw-headline>常量</SPAN></H3> 常量没有前缀和后缀，由小写字母开头.

numberOfRows pi logErrorMsg

<H3><SPAN class=mw-headline>变量</SPAN></H3> 变量没有前缀或后缀. 如前述（也是Prolog的要求），变量以大写字母开头，文档中变量用绿色. </P>

X File OutputStream

<H3><SPAN class=mw-headline>谓词</SPAN></H3> 谓词没有前缀. 不过，“try”可用来标示谓词是确定的，尤其是用来区分一个谓词的确定版本和与其相应的过程版本. 后者会产生异常来代替失败. 如：</P>

trySetValue : (integer Value) determ (i). setValue : (integer Value) procedure (i). 以isXxxx及hasXxxx的形式作为测试谓词是个好方法（当然名称也要对得上号）. </P> 谓词没有后缀，除非需要用它来避免混淆，并推荐使用以下的后缀：</P> <UL> <LI><B>_fact</B> nondeterm fact <LI><B>_nd</B> nondeterm/multi <LI><B>_err</B> erroneous <LI><B>_fail</B> failure <LI><B>_dt</B> determ <LI><B>_multi </B>multi 注意，一般<I>multi</I> 谓词使用<B>_nd</B>做后缀，但如果情况需要也可以用<B>_multi</B>. </LI></UL>

setWindowFont member member_nd ganttBar_fact

<H3><SPAN class=mw-headline>域</SPAN></H3> 域没有前缀. _list用于不具有（事关）域名的表（list）域的后缀，例如，一个数据库的记录是数值表，则记录的域名以数值表为好，就可以用这样的后缀. 注意域名以小写字母开头. 同样的方法适用于串、整数等域的类似情况. </P>

string value record record_list

<H3><SPAN class=mw-headline>类与接口</SPAN></H3> 类与接口没有前辍. </P>

string inputFile template inputStream

COM接口传统上是以"I"开头的，这个"I"保留下来了，但要改为小写：</P>

iUnknown iDispatch

<SPAN class=mw-headline>格式</SPAN></H2> 本节细述程序代码的格式. 格式是指断行，缩排，列排（列对齐）等. 缩排是指在一行的起始留出若干空格；而列对齐涉及的是非行首构件的排列问题. <H3><SPAN class=mw-headline>断行</SPAN></H3> <P>断行应遵循以下规则：</P> <UL> <LI>外层的结构总在内层结构前断行. </LI></UL> <UL> <LI>不同谓词的子句间至少用一空行加以分隔. </LI></UL> <UL> <LI>同一谓词的子句间<B>不要</B>用空行分开. </LI></UL> <UL> <LI>段关键字前至少留出一行空行. </LI></UL> <UL> <LI>谓词调用不是嵌套时，自己独占一行. </LI></UL> <UL> <LI>截断（不管它看起来多微小）占一行. </LI></UL> <UL> <LI>子句头部独占一行. </LI></UL>

<H3><SPAN class=mw-headline>缩排</SPAN></H3> <P>缩排是指行首留出若干空格，它有以下规则：</P> <UL> <LI>缩排的宽窄量要一致（比如都占4个空格）. </LI></UL> <UL> <LI>如果圆括号中的一组内容必须要分成若干行，则应在左括号后立即断行，之后的缩进应该增加一步，而不要与上面的左括号对齐. </LI></UL> <H3><SPAN class=mw-headline>列对齐</SPAN></H3> <P>不使用列对齐（列对齐是指使各个不在行首的结构排列对齐，在行首的构件的对齐使用缩排的规则）. </P> <H3><SPAN class=mw-headline>空格符</SPAN></H3> <UL> <LI>逗号后加空格. </LI></UL> <UL> <LI>在函子（包括表）内，逗号后的空格可以略去. </LI></UL> <UL> <LI>谓词、事实、常数的声明中，在“:”前后加空格. </LI></UL> <UL> <LI>圆括号前后不要有空格，除非圆括号与诸如“ :- ”，“ : ”这样的通常前后有空格的记号相邻. </LI></UL> <H2><SPAN class=mw-headline>结构</SPAN></H2> <P>这节逐项讨论结构. </P>

<H3><SPAN class=mw-headline>段</SPAN></H3> <P>段关键字独占一行. 段关键字<B>不</B>缩进，该段内的构件缩进一步. 段间至少用一个空行来分隔. </P>

clauses p.

clauses q.

<H3><SPAN class=mw-headline>类、接口、实现等</SPAN></H3> <P>类的起始与结束各自独占一行. 类的结束行总是包含有类的标识名，类中的段关键字不要缩进. </P>

class specialOutputFile : outputFile predicates ... end class specialOutputFile

其它的（接口、实现等）与此相同.

<H3><SPAN class=mw-headline>谓词声明</SPAN></H3> <P>谓词声明<B>总</B>含有参数名，这些名字使用变量的格式. <B>procedure</B>模式的声明可以省略. </P>

predicates increment : (integer X) -> integer Y.   bubbleSort : (integer_list Input) -> integer_list SortedList. myPredicate_nd : (           aVeryLongDomainName StrangeFirstParamanter,             anotherLongDomainName PlainSecondParameter) nondeterm (i,o) determ (i,i).

<P>注意左括号之后的断行及其后增加了的缩进. </P> <H3><SPAN class=mw-headline>域</SPAN></H3> <P>函子<B>总要</B>为其参数命名；这些名字使用变量的格式. 如果一个域声明分为若干行，不管所有函子在一行还是分为若干行，也不管函子的参数都在一行还是分占若干行，都应在等号后做第一次断行. </P>

domains value = int(integer Value); real(real Value); str(string Value).

domains aVeryLongDomainName = x(integer X); y(integer Y).

domains anotherLongDomainName = aFunctorWithManyArguments(           integer X,            integer Y,            integer Z,            integer RedColourComponent,            integer BlueColourComponent,            integer GreenColourComponent).

<H3><SPAN class=mw-headline>子句</SPAN></H3> <P>子句的头部独占一行. 子句体中各调用独占一行. 如果一个子句的头部必须断行，则其参数应比头部多缩进两步，因为不这样它的缩进位置就会与子句体一样. </P>

clauses myPredicate(X, Y) :- callNoOne(X, Y, Z), !,       callNoTwo(Z, Y). myPredicate(X, Y) :- callNoThree(X, Y).

clauses aPredicateWithManyArguments(FirstArgument, SecondArgument,           X, Y, Z, ErrorNo, ErrorMsg) :- callNoOne(FirstArgument, SecondArgument, X, Y, Z,           ErrorNo, ErrorMsg), callNoTwo(…), …

<H4><SPAN class=mw-headline>Non-deterministitic Loops</SPAN></H4> <P>对非确定调用结果的循环是Prolog中常用的一种结构. 对这种结构建议把循环体加深缩进： </P>

clauses myPredicate :- member(X, [1,2,3,4,5,6]), doAction(X), % extra indentation in the "loop body" fail. myPredicate.

<P>可能的话，尽量使用 <B>foreach</B> 结构. </P>

<H2><SPAN class=mw-headline>Microsoft Word中的代码格式化</SPAN></H2> <P>本节给出一些在Microsoft Word中便于格式化代码的提示. </P> <P>可以构造一个名为 <I>code</I> 的段落格式，再构造一些字符格式：<I>keyword</I>, <I>parameter</I>, <I>var</I>, <I>literal,</I> 等. </P> <P><I>code</I> 的段落格式可以用如下的属性：</P> <UL> <LI>基于正文段落格式，它可以为下面的代码段提供合适的空间. </LI></UL> <UL> <LI>关闭拼写检查等. </LI></UL> <UL> <LI>缩进一个量，并将缺省的tab设为与这个量一致. 这个量可以用0.63cm，因为这也是其它段落格式的缺省值. </LI></UL> <UL> <LI>设置孤行控制等内容，避免程序不必要地跨页. <I>keyword</I> 字符样式把字体改为Arial，粗体，暗绿色；<I>var</I> 把颜色改为绿色，<B>literal</B> 把颜色改为蓝色. </LI></UL> <P>输入代码时，先选择code段落格式. 输入中使用软回车（shift+newline），用tab键缩进. </P> <P><B>节省时间</B>：可以用格式刷来搞定各种关键字的格式问题. </P>