Az ANVIL

Nyelv Leírás

Az Anvil a C-hez hasonlító nyelvek osztályba tartozik, de sok tulajdonságot vett át a Java,  a  Python nyelvekből, és egy keveset pedig a Perl-ből.


Nyelvtan, Grammar

A nyelvtan nem mondható jól formáltnak. Megpróbáltak jól olvasható nyelvtant alkotni. Néhány szabály ismételve lett a könnyebb érthetőség kedvéért. Rövid magyarázat a szintaxishoz:

  module := "module" [ symbolname ] "{" module-decls "}"
  module :=  module-decls
  module-decls =( import      | constant      | variable      | function      | namespace     | class      | interface ) *

  import        := "import" import-source [ import-as ] ";"
  import        := "import" import-source ":" import-list ";"
  import-name   := symbol ( "." symbol )*
  import-source := ( string-literalpath | import-name )
  import-as     := "as" symbolnewname
  import-list   := "*"
  import-list   := import-entity  ( "," import-entity )*
  import-entity := import-name ["." "*"] [ import-as ]

  constant      := "const" constant-decl ( "," constant-decl )* ";"
  constant-decl := symbolname "=" exprinitializer

  variable      := "var" variable-decl ( "," variable-decl )* ";"
  variable-decl := symbolname [ "=" exprinitializer ]

  namespace :=  "namespace" namespace-name      "{"  ( import  | constant   | variable    | function   | namespace   | class ) *    "}"
  namespace-name := symbol ( "." symbol )*

  entity := ( "module" "." symbol | symbol ) ( "." symbol ) *
  class  := 
    "class" symbolname 
    [ "extends" entityclass
    [ "implements" entityinterface ( "," entityinterface )* ]
    "{" 
      ( import
      | constant 
      | variable 
      | function 
      | "static" variable 
      | "static" function 
      | class 
      )* 
    "}"

  entity := ( "module" "." symbol | symbol ) ( "." symbol ) *
  interface := 
    "interface" symbolname  
    "extends" [ entityinterface ( "," entityinterface ) * ]
    "{" 
       ( import
       | constant 
       | variable
       | "static" function
       | interface-method 
       | interface
       )* 
    "}"

  arguments        := [ argument ( "," argument )* ] [ ".." symbolcollector ]
  argument         := symbolname [ = exprconstant ]
  interface-method := "function" symbolname  "(" arguments ")" ";"

  arguments := [ argument ( "," argument )* ] [ ".." symbolcollector ]
  argument  := symbolname [ = exprconstant ]
  function  := 
    ["synchronized"] "function" symbolname "(" arguments ")" 
    "{" 
      ( function 
      | import 
      | statement ) * 
    "}"

  arguments        := [ argument ( "," argument )* ] [ ".." symbolcollector ]
  argument         := symbolname [ = exprconstant ]
  inline-function := "{" "|" arguments "|" statement * "}"
  inline-function := "{" "||" statement * "}"

  statement :=    ( assert     | break     | catch     | continue     | empty     | exit     | expr-stmt     | finally     | if     | print     | return     | synchronized    | throw     | try     | yield     | [ label ] block      | [ label ] do     | [ label ] for     | [ label ] foreach     | [ label ] switch     | [ label ] while   )

  assert := "assert" exprcondition ";"

  break  := "break" [ symbollabel ] [ stmt-modifier ] ";"

  continue  := "continue" [ symbollabel ] [ stmt-modifier ] ";"
  continue  := "continue" [ symbollabel ] "case" exprconstant  [ stmt-modifier ] ";"
  continue  := "continue" [ symbollabel ] "default" [ stmt-modifier ] ";"

  empty := ";"

  exit := "exit" [ expr-listvalues ] [ stmt-modifier ] ";"

  expr-stmt := expr-start [ stmt-modifier ] ";"

  print := ("print" | "println" | "printbr" )    [ print-expr-listvalues ] [ stmt-modifier ] ";"
  print-expr-list := expr-start ( ( "," )+ expr-start ) *

  return := "return" [ expr-listvalues ] [ stmt-modifier ] ";"

  throw := "throw" expr-listthrowable [ stmt-modifier ] ";"

  yield := "yield" expr-listvalues [ stmt-modifier ] ";"

  stmt-modifier := ( "if" exprcondition | "while" exprcondition )

  label := symbollabel ":"

  block  := "{" statement * "}"

  catch := "catch" "(" assignable-exprthrowable ")" statement
  catch := "catch" "(" assignable-exprthrowable ":" identifiertype ")" statement
  catch := "catch" "(" assignable-exprthrowable ":" expressioncondition ")" statement

  do := "do" statement "while" "(" expr-startcondition ")" ";"

  finally := "finally" statement

  for := "for" "(" exprs ")" statement
  for-exprs := [ for-expr-listinit ] ";" [ exprcondition ] ";" [ for-expr-listaction
  for-expr-list := expr-start ( "," expr-start ) *

  foreach :=   "foreach" "(" [[[[ foreach-expr-listindices ] ";"]    [ foreach-expr-listkeys    ] ";"
                     [ foreach-expr-listvalues  ] ";"] expriterable ")" statement
  foreach-expr-list := assignable-exprtarget ( "," assignable-exprtarget ) *

  if := "if" "(" expr-startcondition ")" statementthen [ "else" statementelse ]

  switch := 
    "switch" "(" expr-startcandidate ")" 
    "{"
      ( "case" exprvalue ( "," exprvalue )* ":"  statement *
      | "default" ":" statement *
      ) *
    "}"

  synchronized := "synchronized" "(" expr-startobject ")" statement

  try := "try" statement ( catch )* [ finally ]

  while := "while" "(" expr-startcondition ")" statement

  expr-start := assignment | expr
  expr-list  := expr ( "," expr )*

  assignable-expr := ["&"] identifier accessor
  assign-target   := assignable-expr
  assign-targets  := assign-target ("," assign-target ) *
  assignment      := assign-targets "=" expr-list
  assignment      := assign-targets "+=" expr-list
  assignment      := assign-targets "-=" expr-list
  assignment      := assign-targets "*=" expr-list
  assignment      := assign-targets "/=" expr-list
  assignment      := assign-targets "%=" expr-list
  assignment      := assign-targets "&=" expr-list
  assignment      := assign-targets "?=" expr-list

  expr :=      foreach-expr   | pipe-expr   | map-expr   | cond-expr   | range-expr   | or-expr   | xor-expr   | and-expr   | eq-expr   | rel-expr   | in-expr   | add-expr   | mul-expr   | match-expr   | unary-expr   | cast-expr   | augment-expr   | is-expr   | has-expr   | lazy-expr   | primary

  foreach-expr := expr "foreach" inline-function 

  pipe-expr := expriterable "->" exprcallable

  map-expr := exprkey "=>" exprvalue

  cond-expr := exprcondition "?" exprif-true ":" exprif-false
  cond-expr := exprcondition "?" exprif-true ":" 
  cond-expr := exprvalue "??" exprif-false

  range-expr := exprstart ".." exprend
  range-expr := exprstart ".."
  range-expr := ".." exprend
  range-expr := ".."

  or-expr  := expr "||" expr
  xor-expr := expr "^^" expr
  and-expr := expr "&&" expr

  eq-expr := expr "==" expr
  eq-expr := expr "!=" expr
  eq-expr := expr "===" expr
  eq-expr := expr "!==" expr
  eq-expr := expr "<=>" expr
  eq-expr := expr "<==>" expr

  rel-expr := expr ">" expr
  rel-expr := expr ">=" expr
  rel-expr := expr "<" expr
  rel-expr := expr "<=" expr

  in-expr := exprelement "in" exprset
  in-expr := exprelement "!" "in" exprset

  add-expr := expr "+" expr
  add-expr := expr "-" expr
  add-expr := expr "&" expr

  mul-expr := expr "*" expr
  mul-expr := expr "/" expr
  mul-expr := expr "%" expr

  match-expr := exprcandidate "~" exprpattern
  match-expr := exprcandidate "!~" exprpattern

  unary-expr := "!" expr
  unary-expr := "+" expr
  unary-expr := "-" expr
  unary-expr := "*" expriterable
  unary-expr := "copyof" exprcopyable
  unary-expr := "cloneof" exprcloneable
  unary-expr := "sizeof" expr
  unary-expr := "classof" expr

  cast-expr := "(" "boolean" ")" expr
  cast-expr := "(" "int" ")" expr
  cast-expr := "(" "float" ")" expr
  cast-expr := "(" "string" ")" expr

  augment-expr := "++" assignable-expr
  augment-expr := "--" assignable-expr
  augment-expr := assignable-expr "++"
  augment-expr := assignable-expr "--"

  is-expr := expr "is" ["!"] "defined"
  is-expr := expr "is" ["!"] "undefined"
  is-expr := expr "is" ["!"] "null"
  is-expr := expr "is" ["!"] "boolean"
  is-expr := expr "is" ["!"] "int"
  is-expr := expr "is" ["!"] "float"
  is-expr := expr "is" ["!"] "string"
  is-expr := expr "is" ["!"] "&"
  is-expr := expr "is" ["!"] ".."
  is-expr := expr "is" ["!"] "=>"
  is-expr := expr "is" ["!"] "(" ")"
  is-expr := expr "is" ["!"] "{" "}"
  is-expr := expr "is" ["!"] "[" "]"
  is-expr := expr "is" ["!"] "class"
  is-expr := expr "is" ["!"] entityclass-of-interface

  has-expr := expr "has" ["!"] symbolname
  has-expr := expr "has" ["!"] "(" expr ")"

  lazy-expr := "^" primary

  primary :=      ( parenthesized     | literal     | import-expr     | defined-expr     | delete-expr     | list-expr     | tuple-expr     | array-expr     | type-expr    | new-expr     | inline-function      | call-expr     | ref-expr     | identifier ) accessor *

  parenthesized := "(" expr ")"

  import-expr := import "(" exprpath ")"

  defined-expr := "defined" identifier 
  defined-expr := "defined" "(" identifier ")"

  delete-expr := "delete" identifier 
  delete-expr := "delete" "(" identifier ")"

  tuple-expr := "(" ")"
  tuple-expr := "(" expr "," ")"
  tuple-expr := "(" expr-list [","] ")"

  list-expr := "\{" expr-list [","] "}"
  list-ctor := "\{" comprehension-foreach  "}"
  comprehension-foreach :=  "foreach" "(" ... ")" comprehension
  comprehension-if ::= "if" "(" expr ")" comprehension
  comprehension := comprehension-foreach | comprehension-if | expr

  array-expr := "[" array-mapping ("," array-mapping )* [","] "]"
  array-expr := "[" comprehension-foreach "]"
  array-mapping := exprkey ["=>" exprvalue ]
  comprehension-foreach :=  "foreach" "(" ... ")" comprehension
  comprehension-if ::= "if" "(" expr ")" comprehension
  comprehension := comprehension-foreach | comprehension-if | expr

  type-expr := ( "boolean" | "int" | "float" | "string" )

  new-expr := "new" identifierclass "(" parameters ")"
  new-expr := "new" identifierclass  inline-functionparameter  
  param := [ symbolname "=" | "@" ] expr
  parameters := param ( "," param )*

  identifier :=      [ "var" ]     [ symbol | "module" | "class" | "static" | "this" | "super" ]     ( "." ( symbol | "this" ) ) *
                           [ "." ( "class"          | "sizeof"          | "copyof"           | "cloneof" )     ]

  call-expr :=  identifiercallable "(" parameters ")"
  call-expr :=  identifiercallable  inline-functionparameter   
  parameters := param ( "," param )*
  param := [ symbolname "=" | "@" ] expr

  ref-expr := "&" identifierlocal-or-parameter

  accessor :=      acc-call   | acc-closure-call   | acc-invoke   | acc-attribute   | acc-reference 

  acc-call   := "(" parameters ")"
  parameters := param ( "," param )*
  param := [ symbolname "=" | "@" ] expr
  acc-closure-call := inline-functionparameter

  acc-invoke := "." symbolname "(" parameters ")"
  acc-invoke := "." "(" expr ")" "(" parameters ")"
  acc-invoke := "." symbolname  inline-functionparameter 
  acc-invoke := "." "(" expr ")" inline-functionparameter
  parameters := param ( "," param )*
  param := [ "@" ] expr

  acc-attribute  := "." symbolattribute-name

  acc-reference  := "[" expr-list "]"
  acc-reference  := "[" "]"

  literal :=      int-literal   | float-literal   | string-literal   | pattern-literal   | "inf"   | "false"   | "true"   | "undefined"
 


Lexikális elemzés, Lexical analysis

Az Anvil programot egy elő-feldolgozó komponens olvassa el.. Az elő-feldolgozó a tokenek listáját a lexikális elemzőtől kapja.

A lexikális elemző az ISO-8859-1 karakter készletet használja.

Ebben vannak  Megjegyzések, Azonosítók, kulcsszavak és Literálok.

Megjegyzések:

A megjegyzések törölve lesznek, nem lesz belőlük token. Négy fajta megjegyzés van:.

1. Egyszerű sor megjegyzés, ami egy hash karakterrel (#) kezdődik és  a sor végéig tart.

  #
  # $Id: index.nvl,v 1.38 2002/01/31 14:35:18 jkl Exp $
  #

2. Egyszerű sor megjegyzés, ami 2 per karakterrel (//) kezdődik és  a sor végéig tart.

  // FIXME: Quick hack

3. Több soros megjegyzés, ami  egy /* kezdődik és */ végződik.

  /* 
   * Comment example
   */

4. Dokumentációs megjegyzés, ami /** kezdődik és */ végződik. Nézd meg az  Anvil dokumentációt részletekért..

  /** 
   * Sets the name of blarg.
   * @param name New name 
   */
   function setName(name) {
     ...
   }

Azonosítók és Kulcsszavak:

Az azonosítók alfa-numerikus karakterek szekvenciájából állnak, és tartalmazhatják az aláhúzást (_). Minden ISO-Latin betű használható. Habár az azonosítók nem kezdődhetnek számmal. Az azonosítók kis-nagybetű érzékenyek, de nincs korlátozás a hosszukra vonatkozólag.

Néhány azonosítót foglalt szónak nevezünk, amik speciális jelentéssel bírnak. A kulcsszavak:

      as         assert    boolean     break
      case      catch      class       classof
      const     copyof     cloneof     continue
      default   defined    delete      do
      else      extends    exit        false
      finally   float      foreach     for
      function  if         implements  import
      in        inf        interface   int
      is        has        module      namespace
      new       null       println     printbr
      print     return     sizeof      string
      static    super      switch      synchronized
      this      throw      true        try
      typeof    undefined  var         while
      yield

Habár a kulcsszavak nem használhatók általános azonosítóként, azért ez elkerülhető a dollár jellel. ($). Ellentétben más nyelvekkel a dollár jel nem jelez előre egy változót; csupán ez is használható eszköz.

Példák:

  $if = 1;
  $for = 10;

Konstans Kulcsszavak

Néhány kulcsszó konstansokat jelöl, akárcsak más nyelvi konstrukciókban. Ezek:

   true   false   null   undefined   inf

Típus kulcsszavak

Néhány az  anvil.lang-ben található típusokat jelöli. Ezek:

   string   int   float

Literálok:

A literálok konstans értékeket jelölnek, amelyek valamilyen típus szerint épülnek fel.

A literálok lehetnek: Sztringliterálok, Egész literálok, Lebegő pontos literálok, Reguláris kifejezések és Operátorok és határoló jelek.

Sztring literálok:

Ezeknek van néhány különleges tulajdonságuk. A sztringeknek van kezdő és bezáró jelük, amely vagy egyszerű felső aposztróf  ('), vagy macskaköröm ("), vagy ferde aposztróf  (`). Nem lehet benne sortörés, vagy kivételes karakterek, mint  backslash.

A hosszú sztringek tripla macskakörömmel kezdődnek és végződnek. ("""). Ezek lehetnek több sorban is.

A Backslash sztring egy backslash-el (\) kezdődik rögtön követve a szimbólummal. 

Az alábbiak beágyazott kifejezések lehetnek a sztringen belül:

Jel Jelentése
\\ Backslash
\' Egyszerű aposztróf
\" Macskaköröm
\` Ferde Aposztróf
\b Csengő
\f Formázott
\n Sortörés
\r Kocsi visszatér
\t Horizontális tabulátor
\xNN 8-bites unicode karakter hexadecimálisan NN
\xNNN 8-bit unicode karakter oktálisan NNN
\uNNNN 16-bit unicode karakter hexadecimálisan NNNN

Implicit sztring konkatenálás

Több sztringet lehetőségünk van eggyé konkatenálni. A megkötés csupán annyi, hogy egyik sztring sem tartalmazhat megjegyzéseket vagy white spaceket.

Példák:

  str = "hello\nworld\n";
  str = 'hello\n' `world\n`; // same as above
  str = 'hello\n' `world\n`; // same as above
  str = \Hello \World;       // "HelloWorld"
  greeting = """Hello!
Time is now ${anvil.time.getTime()}.
Wuzzup?""";
  name = \anvil;

Kifejezések, Expressions

A legfelsőbb szintű kifejezések (expr-start) tartalmazhatnak  felsorolási vagy érték kifejezésére szánt típusokat. Illetve a kifejezéseket használhatjuk mint egy feltétel kifejezéseként, utasításban, vagy akár állhat önállóan egymagában.

  expr := foreach-expr  | pipe-expr  | map-expr   | cond-expr   | range-expr   | or-expr
	| xor-expr   | and-expr  | eq-expr   | rel-expr   | in-expr | add-expr   
	| mul-expr   | match-expr   | unary-expr   | cast-expr  | augment-expr
	| is-expr   | has-expr   | lazy-expr   | primary 

Utasítások, Statements


Az utasítások végrehajtása az elkerülhetetlen útja annak, hogy csináljunk is valamit.

A Definíciós utasításokat a nyelvi konstrukciók bevezetésére használjuk. Ide azok az eszközök tartoznak amelyekkel a kifejezések és más utasítások dolgoznak.

A definíciós utasítások vagy entitásokat definiálnak vagy entitásokat importálnak. Ezek lehetnek:

Az Egyszerű utasítás az ami nem tartalmaz másik utasítást. Ennek három típusa:

  • Utasítások, amelyek a végrehajtás folyamatáért felelősek: Assert, Break, Continue, Exit, Return, Throw, Yield

  • Nyomtatási utasítás: Print

  • Üres utasítás: Empty utasítás

  • A Kifejezés utasítás tartalmaz kifejezést:

      expr-stmt := expr-start [ stmt-modifier ] ";" 
    

    Az Összetett utasítások tartalmazhatnak más utasításokat, és ők tipikusan arra használandók, hogy átvegyék a vezérlést.

      statement := 
        ( assert 
        | break 
        | catch 
        | continue 
        | empty 
        | exit 
        | expr-stmt 
        | finally 
        | if 
        | print 
        | return 
        | synchronized 
        | throw 
        | try 
        | yield 
        | [ label ] block  
        | [ label ] do 
        | [ label ] for 
        | [ label ] foreach 
        | [ label ] switch 
        | [ label ] while 
        ) 
    

    Osztályok, Classes

    Mint már említettem az Anvilen belül minden Objektum. Még az egészek és lebegőpontos kifejezések is. Az objektum valahol az osztály és instancia között helyezkedik el.

    Amikor egy objektum létrejön, akkor egy identitást kap. Ez jelenthet egy rögzített pozíciót a memóriában. Az addressOf() függvény segítségével a címe le is kérdezhető.

    Egy objektum típusa lekérdezhető  a classof obj vagy a  meta attribútumok obj.class segítségével. Mindkét kifejezés egy objektum típussal tér vissza, amely megtalálható az anvil.runtime.Type-ban.

    Néhány Objektum lehet megváltoztathatatlan, ami azt jelenti, hogy a létrejötte után a tartalma nem megváltoztatható. Az ilyen objektum tartalmaz  egészeket, lebegőpontos típust, sztringet, sablonokat.

    A legtöbb objektum tartalma megváltoztatható.  A felhasználó által definiált osztályokkal erre jó példákat lehet adni.

    Amikor egy objektum létrejött az sohase szűnik meg explicit módon.  Habár a Java virtuális gép miatt előfordulhat, hogy többé nem lesz elérhető, aztán a szemétgyűjtő algoritmusnak köszönhetően az objektumok törlődnek, hogy a memória felszabadulhasson.

    Minden osztály egy modulhoz tartozik. A modul egy osztály és függvény gyűjtemény. Egy modulhoz egy instancia tartozik. 

    Az osztályok és modulok három különböző fába csoportosíthatók. Mindegyikük elérése kissé különböző, de érthető.

    Anvil szkript modulok és osztályok
    Ezek Anvil szkriptekkel (and templates) lettek írva. Az alap osztályuk mindig az anvil.lang.object

    Itt található számos callbacks methodus amik aláhúzással kezdődnek. 

     
    Természetes könyvtári modulok és osztályok
    Ezek Javaban lettek írva és integrálták őket az Anvil részeként. Az alap osztályuk mindig az anvil.lang.object.
     
    Elérhető Java csomagok és osztályok
    Bármely Java csomag és osztály elérhető az Anvilből.  Ami kitárja a lehetőségeket a Java felé. Ezeknek az alap osztálya mindig a java.lang.Object

    Hatókör és Entitások, Scopes and entities

    Az Anvil használ statikus beágyazást.  A beágyazáskor neveket vagy ponttal szeparált neveket használunk  (pl. com.acme.tool) amik az entitáshoz kapcsolódnak. Amikor a statikus beágyazás nem alkalmazható, akkor használjuk a dinamikus beágyazást, ami futás időben történik. Instanciáknál akkor történik, amikor egy objektumra a  data.toString() metódust meghívja .

    Az entitások az alábbiak lehetnek:

     

    Az entitások hatókörökben vannak definiálva. Hatókörök, amelyek a szkriptben deklarálhatók:

    Modul
    Modul hatóköre. Tartalmazhat konstansokat, változókat, függvényeket, osztályokat, interfészeket és névtereket. A modulra hivatkozni expliciten lehet, vagy a modul nevével.
    Névtér
    Névtér hatóköre tartalmazhat konstansokat, változókat, függvényeket, osztályokat, interfészeket és névtereket.
    Osztály hatóköre
    Osztály hatóköre tartalmazhat osztály változókat, változókat, konstansokat, függvényeket, metódusokat és osztályokat.. Osztályra hivatkozni az osztályon belül értelemszerűen lehet, azon kívül pedig a nevével.
    Interfész hatóköre
    Interfész hatóköre tartalmazhat változókat, konstansokat, függvényeket, interfész metódusokat és interfészeket.  Az entitások az örökölt interfészben is láthatók.
    Hívható hatókör
    A függvények, metódusok hatóköre tartalmazhat  lokális változókat, paramétereket és függvényeket, metódusokat. Habár ezek az entitások nem láthatók a függvényeken kívül, azért természetesen a függvények elérhetik a deklarált entitásokat a szülő függvényeken. 
    Importált hatókör
    Más hatókörök (vagy interfészek) importálhatnak más hatóköröket az  import  utasítást használva.
    Szerver névtér
    A szerver konfiguráció lehetővé teszi, hogy névtereket definiáljunk.  Ezekre a nevükkel hivatkozhatunk

     

    Amikor beágyazáskor egy névre keresünk,  akkor  a keresés mindig az eredeti hatókörtől kezdődik és folytatódik lefelé egészen addig amíg egy entitást nem talál. Ha minden más hatókór érvénytelen , akkor az utolsó kipróbált hatókör mindig az anvil.lang modul és hiba generálódik, ha nem talált egyezést.

    Engedély, Permissions

    Az anvil verem alapú engedély ellenőrzést használ annak a megvizsgálására, hogy jogosult vagy e egy akció végrehajtására.

    Alapértelmezés szerint az ellenőrzés ki van kapcsolva, és egyébként is az ellenőrzés engedélyezéséhez szükség van legalább egy vezérlési elv (policy) beállítására. A  vezérlési elvek domainonként állíthatók.

    Az elvek tartalmaznak egy jogosultság gyűjteményt, amelyek a jogosultságokkal együttesen alkotják a finom-hangolt biztonsági elvet. Futási időben  megszerezhetsz jogosultsági köröket, de ha ez egyszer ez már megtörtént, akkor futás időben már nem vehető vissza.

    A Citizens és a tribes is tartalmazhatnak jogosultságokat.. 

    Amikor egy jogosultsághoz kötött akció (mint fájl olvasás, írás vagy socket létrehozás) végrehajtódna, akkor előbb konzultál a biztonsági elvel:

    Sablonok, Templates

    Mint ahogyan azt korábban említettem az Anvil egy szerver oldali alkalmazás, amely a Java nyelvre épülő szkript nyelvből és egy template nyelvből áll. Szóval az Anvil igazából két nyelvet tömörít magába. Az alábbiakban a template nyelvről lesz szó.

    Az Anvil sablonok nagyon egyszerű szkriptek. A kódolás alapja ugyanaz, de a funkciók korlátozva vannak.

    A sablonokat felosztja számítási utasításokra, címkékre, adatokra és megjegyzésekre az  anvil.parser.Parser, amely rugalmas, de alapvetően címke utasítás orientált előfeldolgozó.  Érdekessége, hogy sohasem generál hibát.  Az előfeldolgozó funkciói az anvil.xml.parse()-en kersztűl használhatóak..

    A sablon nyelvtan áttekintése  itt található.

    A <module>, <namespace>, <class>, <function>, <var> és <const> címkék a nyelv deklarálásának konstruktív eszközei. 

    A legtöbb sablon utasítás címke funkciója megfelel a hasonló szkript utasítás funkciójának.

    További információkat a karakter adatok kezeléséről  itt olvashatsz.

    Saját címkék természetesen definiálhatók.

    Anvil dokumentáció, Anvildoc

    Az Anvil szkript és sablon nyelv a java-stílusú megjegyzéseket használja.

    A szkripten belüli megjegyzés szintaxisa a következő:

     /**
      * Sets the name of user.
      * @synopsis void setUser(User user)
      * @param user User object
      * @author zorg
      */
     function setUser(user) { ... }
    

    A sablonon belüli megjegyzés szintaxisa a következő:

     <!--/**
          *  Shows the user's information.
          *  @param user User object
          *  ...
          */-->
     <function name=showUser param=user>...</function>
    

    A megjegyzések csatolhatók modulokhoz, névterekhez, osztályokhoz, iterfészekhez, fügvényekhez, konstansokhoz és változókhoz.

    A következő címkék jelenhetnek meg a szkriptben, sablonokban és Java könyvtárakban:

    @attribute identifier text
    Ez a címke nem állhat önállóan, hanem ez egy osztály dokumentáció része lehet. Ezt különböző attribútum elérések megjelölésére  használják általában.
     
    @author text
    A szerző feltüntetésére szolgál.
     
    @category text 1
    Specifikálja a logikai "kategóriáját" a cél entitásnak.
     
    @default text
    Megjegyzés az alapértelmezett érték feltüntetésére. Csak a @param címkével használatos.
     
    @exclude 1
    Jelzi, hogy ezt az entitást nem kell megmutatni a dokumentum megjelenítőben. 
     
    @operator identifier text
    Ez a címke nem állhat egyedül.  Általában egy osztály dokumentáció része. Annak a jelzésére szolgál, hogy a különféle operátorokat mikor használhatja egy instancia vagy egy osztály szintű kérés.
     
    @param identifier text
    Paraméter hozzáadása a "Paraméterek" részhez.
     
    @reference identifier text
    Ez a címke nem állhat egyedül.  Általában egy osztály dokumentáció része. A különböző referencia elérések (self[expr]) jelzésére szolgál, amelyek egy instancia vagy osztály szintű kéréshez tartoznak.
     
    @return text
    A "Visszatérési" részhez adandó leíró szöveg. Ez lehet egy visszatérési típus, vagy egy érték tartomány is.
     
    @see text
    Egy linket ad a dokumentáció kapcsolódó részeihez.
     
    @since text
    Kiírja  a verziót, amely óta ez a rész elérhető.
     
    @throws identifier text
    Jelzi, hogy ezek a kivételek váltódhatnak ki kritikus esetkben.
     
    @type text
    Jelzi a paraméter típusát. Ez a címke csakis a @param címkével együtt használható.
     
    @version text
    Az API verziójának jelzésére szolgál.
     
    @define identifier text
    Paraméter hozzáadása egy függvényhez vagy metódushoz. 

     

    1: Címkéket nem használ a dokumentáció megjelentő.
     

    Ha a címkének van azonosítója, akkor ez opcionálisan mellékelhető egy macskakörömmel ("), ami lehetőséget ad arra, hogy whitespaceket legyenek egy azonosítóban.  A következő címkék megjelennek az alap java könyvtárakban, ahol ők szükségesek a dokumentáció szövegkörnyezetének megállapításához:

    @class identifier text
     
    @const identifier text
     
    @constructor identifier text
     
    @function identifier text
     
    @interface identifier text
     
    @member identifier text
     
    @method identifier text
     
    @module identifier text
     
    @namespace identifier text
     
    @var identifier text