This section defines lexical details of the Levi language.
while1
is an identifier but while
is not.
Examples of legal string literals:
"" "&!88" "use \n to denote a newline character" "use \" to for a quote and \\ for a backslash"
"unterminated "also unterminated \" "backslash followed by space: \ is not allowed" "bad escaped character: \a AND not terminated
=:,+-==>>>>=[<<\\(-o-)//{<<=(!!=--++]});.../*
# this is a comment # and so is # this # and so is # this %$!#
The scanner should recognize and ignore comments (there is no COMMENT token).
For the most part, the token to produce should be self-explanatory. For
example, the
+
symbol should produce the
CROSS
token, the
-
symbol should produce the
DASH
token, etc. The set of tokens can be found in
frontend.hh
or in the switch in tokens.cpp
. The LCURLY
token refers to a left curly brace,
{
.
the RCURLY
refers to a right curly brace,
}
.
The lexical structure of Levi is fairly straightforward, and largely similar to C. There are a few notable details, some of which are departures from C:
\\(-o-)//
produces the THRASH
token....
produces the SINK
token.>>
and <<
produce INPUT
and OUTPUT
, respectively.thrash
,
and
sink
,
are keywords of the language. They produce the
THRASH
,
and
SINK
,
tokens, respectively.file
produces the FILE
token&&
and ||
are NOT in the language . Instead "logical and" is represented by the string and
and "logical or" is represented by the string or
.
This section described the syntax of the Levi language.
While the canonical reference for Levi syntax is its context-free grammar, there are a couple of "standout" points which deserve special attention for their deviation from C:
myfn : (a:int, b:int, c:int) bool { }
bool myFunction(int a, int b, int c) { }
i:int; i = 4;
is not a legal program, but
i:int; fn : () void { i = 4; }
is legal.
file
.
ofile << "hello";
or
ifile >> var;
is legal.
/********************************************************************* Grammar for programs in the Levi language ********************************************************************/ program ::= globals globals ::= globals decl | /* epsilon */ decl ::= varDecl SEMICOL | fnDecl varDecl ::= name COLON type | name COLON type ASSIGN initializer type ::= datatype | IMMUTABLE datatype datatype ::= primtype LBRACKET INTLITERAL RBRACKET | primtype primType ::= INT | BOOL | FILE | VOID fnDecl ::= name COLON LPAREN maybeformals RPAREN type LCURLY stmtList RCURLY maybeformals ::= formalsList | /* epsilon */ formalsList ::= formalDecl | formalsList COMMA formalDecl formalDecl ::= name COLON type stmtList ::= stmtList stmt SEMICOL | stmtList blockStmt | /* epsilon */ blockStmt ::= WHILE LPAREN exp RPAREN LCURLY stmtList RCURLY | IF LPAREN exp RPAREN LCURLY stmtList RCURLY | IF LPAREN exp RPAREN LCURLY stmtList RCURLY ELSE LCURLY stmtList RCURLY stmt ::= varDecl | loc ASSIGN exp | callExp | loc POSTDEC | loc POSTINC | loc OUTPUT exp | loc INPUT loc | SINK name | RETURN exp | RETURN exp ::= exp DASH exp | exp CROSS exp | exp STAR exp | exp SLASH exp | exp AND exp | exp OR exp | exp EQUALS exp | exp NOTEQUALS exp | exp GREATER exp | exp GREATEREQ exp | exp LESS exp | exp LESSEQ exp | NOT exp | DASH term | term callExp ::= loc LPAREN RPAREN // fn call with no args | loc LPAREN actualsList RPAREN // with args actualsList ::= exp | actualsList COMMA exp term ::= loc | literal | THRASH | LPAREN exp RPAREN | callExp literal : INTLITERAL | STRINGLITERAL | TRUE | FALSE litList : literal | literal COMMA litList initializer : literal | LBRACKET litList RBRACKET loc ::= name | loc LBRACKET exp RBRACKET name ::= ID