
% 
% LSL  grammar.

% Syntax by Aditya Mathur: Started:  June 21, 1993.
% First version: 
% Update: July 11, 1993 (Dave's corrections, Rego's 
%                        suggestion, and many other changes)
%
% Update: July 25, 1993 (Time and key signature rules added).

% Update: July 28, 1993 (Dave's comments and sustain mode).

% Update: August 26, 1993 (Dave's comments, new note id's added,
%		           grammar modified to take care of conflicts
%                          during LALR(1) parser generation).

% The idea of using time in LSL is due to Vernon Rego.
% Evening tea meeting on July 9, 5:15pm at Purdue Union.


% Comment (uncomment) next definition to 
% (not to) obtain numbered grammar rules.

%\def\nextrule/{}

\section{LSL Syntax Conventions}

The syntax of LSL is described  below using 
a modified form of BNF\cite{aho-ullman}.
Nonterminals are in italics, keywords in
{\tt teletype} font, and lexical symbols in
{\bf bold} font. Alternates  of a nonterminal are
separated by the \myalt/  symbol.


\begin{tabbing}
\hskip0.5in\=\hskip1.4in\=\hskip0.4in\=\kill
\nextrule/ \>\nonterm/{lsl-spec}\>
$\rightarrow$\>\term/{\lslabegin/}\\
\>\>\>\nonterm/{spec-module-list}\\
\>\>\>\term/{\lslaend/}.\\[0.1in]


\nextrule/\>\nonterm/{spec-module-list}\>$\rightarrow$\>
\nonterm/{spec-module-list} \nonterm/{spec-module}\\
\nextrule/\>\>\>\myalt/   \nonterm/{spec-module}\\[0.1in]
\nextrule/\>\nonterm/{spec-module}\>$\rightarrow$\>
\term/{\lslspecmod/} \lex/{id} \\
\>\>\>\nonterm/{program-id-list}\\
\>\>\>\nonterm/{global-interaction-list}\\
\>\>\>\nonterm/{declarations}\\
\>\>\> \nonterm/{spec-def-list}\\
\>\>\>\nonterm/{VDAP-list}\\
\>\>\>\lslbegin/ \lex/{id}\\
\>\>\> \nonterm/{spec-def-body}\\
\>\>\>\lslend/ \lex/{id};\\[0.1in]


\nextrule/\>\nonterm/{program-id-list} \>$\rightarrow$\>
\term/{\lslexternal/} \nonterm/{ext-id-list}; \\
\>\>\>\myalt/ \lslempty/ \\[0.1in]



\nextrule/\>\nonterm/{global-interaction-list}\>$\rightarrow$\>
\nonterm/{global-interactions} \nonterm/{global-interaction-list} \\
\>\>\>\myalt/ \lslempty/\\[0.1in]

\nextrule/\>\nonterm/{global-interactions}\>$\rightarrow$\>
\nonterm/{interact-id} \nonterm/{id-list};\\[0.1in]

\nextrule/\>\nonterm/{interact-id}\>$\rightarrow$\>
\term/{\lslimport/} \myalt/ \term/{\lslexport/}\\[0.1in]

\nextrule/\>\nonterm/{spec-def-list}\>$\rightarrow$\>
\nonterm/{spec-def} \nonterm/{spec-def-list} \\
\>\>\>\myalt/ \lslempty/\\[0.1in]

\nextrule/ \> \nonterm/{VDAP-list} \>$\rightarrow$\>
\nonterm/{VDAP-spec} \nonterm/{VDAP-list}\\
\>\>\>\myalt/ \lslempty/\\[0.1in]

\nextrule/ \> \nonterm/{VDAP-spec} \>$\rightarrow$\>
\term/{\lslvdapbegin/}\\
\>\>\> \term/{\langdep/{function}} \\
\>\>\>\term/{\lslvdapend/};\\[0.1in]

\nextrule/\>\nonterm/{spec-def}\>$\rightarrow$\>
\term/{\lslspecdef/} \lex/{id} 
(\nonterm/{spec-par-list})\\
\>\>\>\nonterm/{declarations}\\
\>\>\>\lslbegin/ \lex/{id}\\
\>\>\> \nonterm/{spec-def-body}\\
\>\>\>\lslend/ \lex/{id};\\[0.1in]

\nextrule/\>\nonterm/{spec-def-body}\>$\rightarrow$\>
\nonterm/{spec-command}  \nonterm/{spec-def-body} \\
\>\>\>\myalt/  \nonterm/{spec-command}\\[0.1in]

\nextrule/\>\nonterm/{spec-command}\>$\rightarrow$\>
\nonterm/{named-command}\\
\>\>\>\myalt/ \nonterm/{unnamed-command}\\[0.1in]

\nextrule/\>\nonterm/{named-command}\>$\rightarrow$\>
\nonterm/{name-tag-list} \nonterm/{unnamed-command}\\[0.1in]

\nextrule/\>\nonterm/{name-tag-list}\>$\rightarrow$\>
\lex/{id} :: \nonterm/{name-tag-list}\\
\>\>\>\myalt/ \lex/{id} ::\\[0.1in]




\nextrule/\>\nonterm/{unnamed-command}\>$\rightarrow$\>
\nonterm/{set-globals-command}\\
\>\>\>\myalt/ \nonterm/{play-command} \\
\>\>\>\myalt/  \nonterm/{notify-command} \\
\>\>\>\myalt/  \nonterm/{dtrack-command} \\
\>\>\>\myalt/  \nonterm/{atrack-command} \\
\>\>\>\myalt/  \nonterm/{assign-command} \\
\>\>\>\myalt/  \nonterm/{loop-command} \\
\>\>\>\myalt/  \nonterm/{if-command} \\
\>\>\>\myalt/  \nonterm/{specdef-use-command} \\
\>\>\>\myalt/  \nonterm/{VDAP-call-command} \\
\>\>\>\myalt/  \nonterm/{turn-command} \\
\>\>\>\myalt/  \nonterm/{toggle-command}\\
\>\>\>\myalt/  \nonterm/{sync-command}\\[0.1in]


\nextrule/\>\nonterm/{set-globals-command}\>$\rightarrow$\>
\term/{\lslset/} \nonterm/{global-par-list};\\

\nextrule/\>\nonterm/{global-par-list}\>$\rightarrow$\>
\nonterm/{global-par-list}, \nonterm/{global-par}\\
\>\>\>\myalt/  \nonterm/{global-par}\\[0.1in]

\nextrule/\>\nonterm/{global-par}\>$\rightarrow$\>
\nonterm/{score-const-id}\\
\>\>\> \myalt/ \nonterm/{device-const-id}\\[0.1in]


\nextrule/\>\nonterm/{play-command}\>$\rightarrow$\>
\term/{\lslplay/} \nonterm/{play-list}; \\[0.1in]

\nextrule/\>\nonterm/{play-list}\>$\rightarrow$\>
\nonterm/{pattern-specifier} \myparallel/ \nonterm/{play-list} \\
\>\>\>\myalt/ \nonterm/{pattern-specifier} \&\&
\nonterm/{play-list}\\
\>\>\>\myalt/  \nonterm/{play-list}\\[0.1in]


\nextrule/\>\nonterm/{pattern-specifier}\>$\rightarrow$\>
\lex/{id} \\
\>\>\>\myalt/   \lex/{constant}\\
\>\>\>\myalt/ \nonterm/{specdef-use-command}\\
\>\>\>\myalt/ \nonterm/{VDAP-call-command}\\
\>\>\>\myalt/ \nonterm/{pattern-specifier} \nonterm/{play-pars}\\
\>\>\>\myalt/ ( \nonterm/{play-list} ) \\[0.1in]


\nextrule/\>\nonterm/{play-pars}\>$\rightarrow$\>
\term/{\lslwith/} \nonterm/{tagged-list}\\[0.1in]

\nextrule/\>\nonterm/{tagged-list}\>$\rightarrow$\>
\nonterm/{tagged-list}, \nonterm/{tags}\\
\>\>\>\myalt/  \nonterm/{tags}\\[0.1in]

\nextrule/\>\nonterm/{tags}\>$\rightarrow$\>
\nonterm/{score-const-id} \\
\>\>\>\myalt/ \nonterm/{device-const-id} \\[0.1in]



\nextrule/\>\nonterm/{score-const-id}\>$\rightarrow$\>
\nonterm/{score-tag} = \nonterm/{const-id}\\
\>\>\> \myalt/ \term/{\lslmm/} \nonterm/{mmspec}\\
\>\>\> \myalt/ \nonterm/{mode-specifier}\\[0.1in]


\nextrule/\>\nonterm/{const-id} \>$\rightarrow$\>
\lex/{constant}\\
\>\>\>\myalt/  \nonterm/{dotted-id}\\[0.1in]

\nextrule/\>\nonterm/{dotted-id}\>$\rightarrow$\> 
.\lex/{id}\\[0.1in]


\nextrule/\>\nonterm/{score-tag}\>$\rightarrow$\>
 \term/{\lslkey/}\\
\>\>\> \myalt/   \term/{\lsltimesig/}  \\[0.1in]


\nextrule/\>\nonterm/{device-tag-list}\>$\rightarrow$\>
\nonterm/{device-const-id} , \nonterm/{device-tag-list} \\
\>\>\>\myalt/  \nonterm/{device-const-id}\\[0.1in]


\nextrule/\>\nonterm/{device-const-id}\>$\rightarrow$\>
\nonterm/{device-tag} = \nonterm/{const-id}\\[0.1in]


\nextrule/\>\nonterm/{device-tag}\>$\rightarrow$\>
\term/{\lslchan/} \myalt/  \term/{\lslinst/}\\[0.1in]




\nextrule/\>\nonterm/{notify-command}\>$\rightarrow$\>
\term/{\lslnotify/} \nonterm/{all-selective} 
\nonterm/{label-parameter}
\nonterm/{event-specifier} \\
\>\>\>\nonterm/{sound-specifier} 
\nonterm/{scope-specifier};\\[0.1in]

\nextrule/\>\nonterm/{all-selective}\>$\rightarrow$\>
\term/{\lslall/} \myalt/   \term/{\lslselective/}
\myalt/  \lslempty/\\[0.1in]


\nextrule/\>\nonterm/{label-parameter}\>$\rightarrow$\>
\term/{\lsllabel/} = \nonterm/{label-list}\\
\>\>\>\myalt/ \lslempty/\\[0.1in]


\nextrule/\>\nonterm/{label-list} \>$\rightarrow$\>
\nonterm/{label-list}, \lex/{id}\\
\>\>\>\myalt/  \lex/{id}\\[0.1in]


\nextrule/\>\nonterm/{event-specifier}\>$\rightarrow$\>
\nonterm/{event-specifier} 
\nonterm/{connector} \nonterm/{event}\\
\>\>\>\myalt/ \nonterm/{event}\\[0.1in]



\nextrule/\>\nonterm/{connector}\>$\rightarrow$\>
\term/{\lsland/} \myalt/ \term/{\lslor/}\\[0.1in]

\nextrule/\>\nonterm/{event}\>$\rightarrow$\>
\term/{\lslrule/} = \lex/{id}\\
\>\>\>\myalt/ \term/{\lslrule/} = 
\lex/{id}:\nonterm/{instance-list} \\
\>\>\>\myalt/  \term/{\lslinstance/}  = 
\nonterm/ {instance-list}\\
\>\>\>\myalt/   \term/{\lslassertion/} = 
\term/{\langdep/{condition}}\\
\>\>\> \myalt/ \term/{\lslrtime/} = \nonterm/{expression} \term/{\lslafter/}
\nonterm/{event}\\
\>\>\> \myalt/ (\nonterm/{event-specifier})\\
\>\>\> \myalt/ \nonterm/{event} (\lslfirst/)\\[0.1in]

\nextrule/\>\nonterm/{instance-list}\>$\rightarrow$\>
\nonterm/{instance-list} \&\& \nonterm/{instance} \\
\>\>\>\myalt/  \nonterm/{instance}\\[0.1in]

\nextrule/\>\nonterm/{instance}\>$\rightarrow$\>
\lex/{string}\\[0.1in]


\nextrule/\>\nonterm/{sound-specifier}\>$\rightarrow$\>
\term/{\lslusing/} \nonterm/{play-list} \\
\>\>\>\myalt/ \lslempty/\\[0.1in]


\nextrule/\>\nonterm/{scope-specifier}\>$\rightarrow$\>
\term/{\lslin/} \nonterm/{tagged-scope-list}\\
\>\>\>\myalt/ \lslempty/\\[0.1in]



\nextrule/\>\nonterm/{tagged-scope-list}\>$\rightarrow$\>
\nonterm/{tagged-scope-list} \lsland/  \nonterm/{tagged-scope}\\
\>\>\>\myalt/ \nonterm/{tagged-scope}\\[0.1in]

\nextrule/\>\nonterm/{tagged-scope} \>$\rightarrow$\>
\nonterm/{scope-tag} =  \nonterm/{scope-tagid-list}\\[0.1in]



\nextrule/\>\nonterm/{scope-tag}\>$\rightarrow$\>
\term/{\lslfilename/} \myalt/    \term/{\lslfunc/}\\[0.1in]

\nextrule/\>\nonterm/{scope-tagid-list}\>$\rightarrow$\>
\nonterm/{scope-tagid-list}, \nonterm/{scope-tagid}\\
\>\>\>\myalt/ \nonterm/{scope-tagid}\\[0.1in]


\nextrule/\>\nonterm/{scope-tagid}\>$\rightarrow$\>
\nonterm/{selector} \myalt/ \lex/{string}\\[0.1in]


\nextrule/\>\nonterm/{dtrack-command}\>$\rightarrow$\>
\term/{\lsltrack/} \nonterm/{dtrack-id-list}
\nonterm/{start-event-spec}
\nonterm/{term-event-spec}\\
\>\>\>\nonterm/{sound-specifier}
\nonterm/{scope-specifier};\\[0.1in]

\nextrule/\>\nonterm/{atrack-command}\>$\rightarrow$\>
\term/{\lslatrack/} \nonterm/{start-event-spec}
\nonterm/{term-event-spec}
\nonterm/{sound-specifier}\\[0.1in]
\nonterm/{scope-specifier};\\


\nextrule/\>\nonterm/{start-event-spec}\>$\rightarrow$\>
\lslwhen/ \nonterm/{event-specifier}
\nonterm/{scope-specifier}\\
\>\>\>\myalt/ \lslempty/\\[0.1in]

\nextrule/\>\nonterm/{term-event-spec}\>$\rightarrow$\>
\lsluntil/ \nonterm/{event-specifier}\\
\nonterm/{scope-specifier}\\
\>\>\>\myalt/ \lslempty/\\[0.1in]





\nextrule/\>\nonterm/{ext-id-list}\>$\rightarrow$\>
\nonterm/{ext-id-list} , \term/{\langdep/{id}}\\
\>\>\>\myalt/  \term/{\langdep/{id}} \\[0.1in]


\nextrule/\>\nonterm/{dtrack-id-list}\>$\rightarrow$\>
\nonterm/{dtrack-id-list} \lsland/ \nonterm/{dtrack-id}\\
\>\>\>\myalt/ \nonterm/{dtrack-id}\\[0.1in]


\nextrule/\>\nonterm/{dtrack-id}\>$\rightarrow$\>
\term/{\langdep/{id}} \nonterm/{init-value}
\nonterm/{capture-specifier} 
\nonterm/{scope-specifier}\\[0.1in]


\nextrule/\>\nonterm/{init-value}\>$\rightarrow$\>
\term/{\lslinit/} = \nonterm/{\langdep/{expression}}\\
\>\>\>\myalt/ \lslempty/\\[0.1in]

\nextrule/\>\nonterm/{capture-specifier} \>$\rightarrow$\>
\term/{\lslcapture/} = \lex/{id}\\
\>\>\>\myalt/ \lslempty/\\[0.1in]


\nextrule/\>\nonterm/{mode-specifier}\>$\rightarrow$\>
\term/{\lslmode/} = \term/{\lslcontinuous/} \myalt/  
\term/{\lslmode/} = \term/{\lsldiscrete/} \myalt/
\term/{\lslmode/} = \term/{\lslsustain/}\\[0.1in]



\nextrule/\>\nonterm/{assign-command}\>$\rightarrow$\>
\nonterm/{selector} := \nonterm/{expression};\\[0.1in]


\nextrule/\>\nonterm/{selector}\>$\rightarrow$\>
\lex/{id} \myalt/ 
\lex/{id}[\nonterm/{element-selector}]\\[0.1in]


\nextrule/\>\nonterm/{element-selector}\>$\rightarrow$\>
expression-list\\[0.1in]

\nextrule/\>\nonterm/{expression-list}\>$\rightarrow$\>
\nonterm/{expression-list} , \nonterm/{expression}\\
\>\>\>\myalt/ \nonterm/{expression}\\[0.1in]

\nextrule/\>\nonterm/{loop-command}\>$\rightarrow$\>
\nonterm/{for-loop} \myalt/   \nonterm/{while-loop}\\[0.1in]

\nextrule/\>\nonterm/{for-loop}\>$\rightarrow$\>
\term/{\lslfor/} \lex/{id} := \nonterm/{expression}
\term/{\lslto/} \nonterm/{expression} 
\nonterm/{step-expression}\\
\>\>\> \nonterm/{statement-body}\\[0.1in]

\nextrule/\>\nonterm/{step-expression}\>$\rightarrow$\>
\term/{\lslstep/} \nonterm/{expression}\\
\>\>\>\myalt/ \lslempty/\\[0.1in]

\nextrule/\>\nonterm/{while-loop}\>$\rightarrow$\>
\term/{\lslwhile/} \nonterm/{condition} \term/{\lsldo/}
\nonterm/{statement-body}\\[0.1in]

\nextrule/\>\nonterm/{statement-body}\>$\rightarrow$\>
\term/{\lslbegin/} \nonterm/{spec-def-body}
\term/{\lslend/}\\
\>\>\>\myalt/ \nonterm/{spec-command};\\[0.1in]

\nextrule/\>\nonterm/{if-command}\>$\rightarrow$\>
\nonterm/{if-then-command} \\
\>\>\>\myalt/  \nonterm/{if-then-else-command}\\[0.1in]

\nextrule/\>\nonterm/{if-then-command}\>$\rightarrow$\>
\term/{\lslif/} \nonterm/{condition} \term/{\lslthen/}
\nonterm/{statement-body}\\[0.1in]

\nextrule/\>\nonterm/{if-then-else-command}\>
$\rightarrow$\>
\term/{\lslif/} \nonterm/{condition} \term/{\lslthen/}
\nonterm/{statement-body} \term/{\lslelse/} 
\nonterm/{statement-body}\\[0.1in]


\nextrule/\>\nonterm/{specdef-use-command}\>
$\rightarrow$\>
\lex/{id} (\nonterm/{actual-par-list});\\
\>\>\>\myalt/ \lex/{id} (~);\\[0.1in]


\nextrule/\>\nonterm/{actual-par-list}\>$\rightarrow$\>
\nonterm/{actual-par-list}, \nonterm/{actual-par}\\
\>\>\>\myalt/ \nonterm/{actual-par}\\[0.1in]

\nextrule/\>\nonterm/{actual-par}\>$\rightarrow$\>
\nonterm/{expression}\\[0.1in]


\nextrule/\>\nonterm/{spec-par-list}\>$\rightarrow$\>
\nonterm/{id-list} \myalt/ \lslempty/\\[0.1in]


\nextrule/\>\nonterm/{VDAP-call-command}\>
$\rightarrow$\>
\langdep/{id} (\langdep/{actual-parameter-list});\\[0.1in]



\nextrule/\>\nonterm/{turn-command}\>
$\rightarrow$\> \term/{\lslturn/} \nonterm/{on-off} 
\nonterm/{device-tag-list};\\[0.1in]

\nextrule/\>\nonterm/{on-off}\> $\rightarrow$\>
\term/{\lslon/}\\
\>\>\>\myalt/  \term/{\lsloff/}\\[0.1in]

\nextrule/\>\nonterm/{toggle-command}\> $\rightarrow$\>
\term/{\lsltoggle/} \nonterm/{toggle-source} = 
\lex/{constant};\\[0.1in]

\nextrule/\>\nonterm/{toggle-source}\> $\rightarrow$\>
\term/{\lslkeyboard/}\\
\>\>\>\myalt/  \term/{\lslmidi/}\\[0.1in]

\nextrule/\>\nonterm/{sync-command}\> $\rightarrow$\>
\term/{\lslsync/} \nonterm/{sync-to-id};\\[0.1in]

\nextrule/\>\nonterm/{sync-to-id}\> $\rightarrow$\>
\term/{\lslprogram/}\\
\>\>\>\myalt/ \nonterm/{sync-par-list}\\[0.1in]


\nextrule/\>\nonterm/{sync-par-list}\>$\rightarrow$\>
\nonterm/{sync-par-list}, \nonterm/{sync-par}\\
\>\>\>\myalt/ \nonterm/{sync-par}\\[0.1in]


\nextrule/\>\nonterm/{sync-par}\>$\rightarrow$\>
\term/{\lslbufsize/} = \term/{\lslconst/} \\
\>\>\>\myalt/ \term/{\lslnoslow/}\\
\>\>\>\myalt/ \nonterm/{mmkeyword} \\
\>\>\>\myalt/ \nonterm/{mmkeyword} \nonterm/{mmspec}\\[0.1in]

\nextrule/\>\nonterm/{mmkeyword}\>$\rightarrow$\>
\term/{\lslmm/} \myalt/ \term/{\lslmmabs/} \myalt/ \term/{\lslmmrel/}\\[0.1in]

\nextrule/\>\nonterm/{mmspec}\>$\rightarrow$\>
\nonterm/{duration-expression} = \term/{\lslconst/}\\[0.1in]

\nextrule/\>\nonterm/{duration-expression}\>$\rightarrow$\>
\nonterm/{duration-expression} \nonterm/{duration-factor}\\
\>\>\>\myalt/ \nonterm/{duration-expression} +
 \nonterm/{duration-factor}\\
\>\>\>\myalt/ \nonterm/{duration-factor}\\[0.1in]

\nextrule/\>\nonterm/{duration-factor}\>$\rightarrow$\>
\nonterm/{duration-attribute}\\
\>\>\>\myalt/ (\nonterm/{duration-expression})\\[0.1in]

\nextrule/\>\nonterm/{duration-attribute}\>$\rightarrow$\>
\term/{\lslf/} \myalt/ \term/{\lslh/}
\myalt/ \term/{\lslq/} \myalt/ \term/{\lsle/}
\myalt/ \term/{\lsls/} \\[0.1in]


\nextrule/\>\nonterm/{declarations}\>$\rightarrow$\>
\nonterm/ {applicability} \nonterm/{const-declaration} 
\nonterm/{var-declaration}\\[0.1in]


\nextrule/ \> \nonterm/ {applicability}\>$\rightarrow$\>
\nonterm/{apply-list}\\
\>\>\>\myalt/ \lslempty/\\[0.1in]

\nextrule/ \> \nonterm/{apply-list}\>$\rightarrow$\>
\nonterm/{apply-list}; \nonterm/{apply-decl}\\
\>\>\>\myalt/ \nonterm/{apply-decl}\\[0.1in]

\nextrule/ \> \nonterm/{apply-decl}\>$\rightarrow$\>
\lslapply/ \nonterm/{tagged-scope-list};\\[0.1in]


\nextrule/\>\nonterm/{const-declaration}\>$\rightarrow$\>
\term/{\lslconst/} \nonterm/{const-list};\\
\>\>\>\myalt/ \lslempty/\\[0.1in]

\nextrule/\>\nonterm/{const-list}\>$\rightarrow$\>
\nonterm/{const-val-pair} \nonterm/{const-list} \\
\>\>\>\myalt/  \nonterm/{const-val-pair}\\[0.1in]

\nextrule/\>\nonterm/{const-val-pair}\>$\rightarrow$\>
\lex/{id} = \lex/{constant} ;\\[0.1in]

\nextrule/\>\nonterm/{var-declaration}\>$\rightarrow$\>
\term/{\lslvar/} \nonterm/{var-decl-list};\\
\>\>\>\myalt/ \lslempty/\\[0.1in] 

\nextrule/\>\nonterm/{var-decl-list}\>$\rightarrow$\>
\nonterm/{var-type-list} ; \nonterm/{var-decl-list} \\
\>\>\>\myalt/  \nonterm/{var-type-list} \\[0.1in]

\nextrule/\>\nonterm/{var-type-list}\>$\rightarrow$\>
\nonterm/{id-list} : \nonterm/{type}\\[0.1in]

\nextrule/\>\nonterm/{id-list}\>$\rightarrow$\>
\lex/{id} , \nonterm/{id-list} \\
\>\>\>\myalt/  \lex/{id}\\[0.1in]

\nextrule/\>\nonterm/{type}\>$\rightarrow$\>
\term/{\lslint/} \myalt/  
 \term/{\lslnote/} \myalt/  
\term/{\lslpattern/} \myalt/  
 \term/{\lslvoice/} \myalt/  
 \term/{\lslfile/} \myalt/ \term/{ksig} \myalt/ \term/{tsig}\\
\>\>\>\myalt/ \nonterm/{array-declarator}\\[0.1in]

\nextrule/\>\nonterm/{array-declarator}\>$\rightarrow$\>
\term/{\lslarray/} [~\nonterm/{range-list}~] \term/{\lslof/}
\nonterm/{type}\\[0.1in]

\nextrule/\>\nonterm/{range-list}\>$\rightarrow$\>
\nonterm/{range-list} , \nonterm/{range}\\
\>\>\>\myalt/ \nonterm/{range}\\[0.1in]

\nextrule/\>\nonterm/{range}\>$\rightarrow$\>
\nonterm/{expression} \term/{..} \nonterm/{expression}\\[0.1in]

\nextrule/\>\nonterm/{expression}\>$\rightarrow$\>
\nonterm/{expression} \nonterm/{addop} \nonterm/{term} \\
\>\>\>\myalt/  \nonterm/{term}\\[0.1in]

\nextrule/\>\nonterm/{term} \>$\rightarrow$\>
\nonterm/{term} \nonterm/{mulop} \nonterm/{factor} \\
\>\>\>\myalt/  \nonterm/{factor}\\[0.1in]

\nextrule/\>\nonterm/{factor}\>$\rightarrow$\>
 ( \nonterm/{expression} ) \\
\>\>\>\myalt/  \nonterm/{unop} \nonterm/{factor} \\
\>\>\>\myalt/  \lex/{id}\\
\>\>\>\myalt/  \lex/{id}(\nonterm/{actual-par-list})\\
\>\>\>\myalt/  \lex/{id}(~)\\
\>\>\>\myalt/  \term/{\lslconst/}\\[0.1in]

\nextrule/\>\nonterm/{condition}\>$\rightarrow$\>
\nonterm/{condition} \nonterm/{relop} \nonterm/{cterm} \\
\>\>\>\myalt/  \nonterm/{cterm}\\[0.1in]

\nextrule/\>\nonterm/{cterm}\>$\rightarrow$\>
\nonterm/{cterm} \nonterm/{logop} \nonterm/{cfactor} \\
\>\>\>\myalt/  \nonterm/{cfactor}\\[0.1in]


\nextrule/\>\nonterm/{cfactor}\>$\rightarrow$\>
\nonterm/{expression}\\
\>\>\>\myalt/ (\nonterm/ {condition})\\
\>\>\>\myalt/ \term/{\lslnot/} \nonterm/{cfactor}\\[0.1in]



\nextrule/\>\nonterm/{addop}\>$\rightarrow$\>
\term/{$+$} \myalt/   \term/{$-$}\\[0.1in]

\nextrule/\>\nonterm/{mulop}\>$\rightarrow$\>
\term/{$*$} \myalt/   \term/{$/$}\\[0.1in]

\nextrule/\>\nonterm/{unop}\>$\rightarrow$\>
\term/{$-$}\\[0.1in]


\nextrule/\>\nonterm/{relop}\>$\rightarrow$\>
\term/{$<$} \myalt/ \term/{$>$} \myalt/ \term/{$<=$} \myalt/
\term/{$=$} \myalt/ \term/{$>=$} \myalt/ \term/{$<>$}\\[0.1in]


\nextrule/\>\nonterm/{logop}\>$\rightarrow$\>
\&\& \myalt/ \myparallel/\\[0.1in]





\end{tabbing}



\section{Lexical Conventions}


Using regular expressions\cite{aho-ullman} we define 
the lexical elements of LSL.

\begin{enumerate}

\item Comments are enclosed inside 
/* and */. Comments may not appear within a token.
A comment within another comment is not allowed.

\item \term/{char} denotes any ASCII character.

\item One or more spaces separates tokens. 
Spaces may not appear within tokens.

\item An \lex/{id} is a sequence of letters or digits
with the first character being a letter.
The underscore (\_) can be used in an identifier.
Upper and lower case letters
are treated as being different in an \lex/{id}.


\begin{tabbing}
\hskip0.3in\=\hskip1.4in\=\hskip0.4in\=\kill
\>\nonterm/{id}\>$\rightarrow$\>
(~\_~)$^*$\nonterm/{letter} (~\nonterm/{letter} \myalt/
\nonterm/{digit} \myalt/ \_~)$^*$\\
\>\nonterm/{letter}\>$\rightarrow$\>[a-zA-Z]\\
\>\nonterm/{digit}\>$\rightarrow$\>[ 0-9 ]
\end{tabbing}



\item A keyword may not be used as an  \lex/{id}.
Upper and lower case are treated differently.

\item A constant can be an integer or a string.
An integer is a sequence of digits.
A string is a sequence of characters enclosed within
double quotes.  As a constant can be interpreted
in a variety of
ways in LSL, we provide below
a complete grammar for constants.


\initgrule/

\begin{tabbing}
\hskip0.3in\=\hskip1.4in\=\hskip0.4in\=\kill

\nextrule/\>\nonterm/{constant}\>$\rightarrow$\>
\nonterm/{integer}\\
\>\>\>\myalt/  \nonterm/{string}\\
\>\>\>\myalt/\nonterm/{time-sig}\\

\nextrule/\>\nonterm/{integer}\>$\rightarrow$\>
\nonterm/{digit}$^+$\\

\nextrule/\>\nonterm/{string}\>$\rightarrow$\> 
``\nonterm/{char-sequence}''\\

\nextrule/\>\nonterm/{char-sequence}\>$\rightarrow$\>
\nonterm/{note-sequence}\\
\>\>\>\myalt/ \nonterm/{key-sig}\\
\>\>\>\myalt/ \nonterm/{file-name}\\
\>\>\>\myalt/ \nonterm/{function-name}\\

\nextrule/\>\nonterm/{note-sequence}\>$\rightarrow$\>
(\nonterm/{note} \myalt/  .\nonterm/{id})$^+$\\
\>\>\>\myalt/  (\nonterm/{note-sequence}: 
\nonterm/{attribute-sequence})\\
\>\>\>\myalt/  (\nonterm/{note-sequence})\\

\nextrule/\>\nonterm/{note}\>$\rightarrow$\>
\nonterm/{note-generic} \nonterm/{note-modifier}\\

\nextrule/\>\nonterm/{note-generic}\>$\rightarrow$\>
\term/{c} \myalt/  \term/{d} \myalt/   \term/{e} \myalt/
\term/{f} \myalt/   \term/{g} \myalt/   \term/{a} \myalt/
\term/{b} \myalt/  \term/{r} \myalt/ 
\term/{C} \myalt/  \term/{D} \myalt/   \term/{E} \myalt/
\term/{F} \myalt/   \term/{G} \myalt/   \term/{A} \myalt/
\term/{B} \myalt/  \term/{R}\\

\nextrule/\>\nonterm/{note-modifier}\>$\rightarrow$\>
\nonterm/{flat-sharp}$^{*}$   \nonterm/{octave}\\

\nextrule/\>\nonterm/{flat-sharp}\>$\rightarrow$\>
\term/{b} \myalt/  \term/{\#}\\

\nextrule/\>\nonterm/{octave}\>$\rightarrow$\>
[\,0-8\,]\\

\nextrule/\>\nonterm/{attribute-sequence}\>$\rightarrow$\>
\nonterm/{attribute}$^+$\\

\nextrule/\>\nonterm/{attribute}\>$\rightarrow$\>
\nonterm/{duration} \nonterm/{tagged-value-list}$^*$\\

\nextrule/\>\nonterm/{duration}\>$\rightarrow$\> 
\nonterm/{simple-duration}\\
\>\>\>\myalt/  ( \nonterm/{duration-expression} )\\

\nextrule/\>\nonterm/{simple-duration} \>$\rightarrow$\>
\term/{f} \myalt/ \term/{h} \myalt/ \term/{q} \myalt/ \term/{e}
\myalt/ \term/{s} \\
\>\>\>\myalt/ \term/{\lslptime/} = \nonterm/{integer}\\

\nextrule/\>\nonterm/{duration-expression} \>$\rightarrow$\>
\nonterm/{duration-expression} \nonterm/{op} 
\nonterm/{simple-duration}\\
\>\>\>\myalt/  \nonterm/{simple-duration}\\
\>\>\>\myalt/  ( \nonterm/{duration-expression} )\\


\nextrule/\>\nonterm/{op}\>$\rightarrow$\> \term/{+} \myalt/   
\lslempty/\\

\nextrule/\>\nonterm/{key-sig}\>$\rightarrow$\>
\nonterm/{pre-defined}\\
\>\>\>\myalt/ \nonterm/{user-defined} \\

\nextrule/\>\nonterm/{pre-defined}\>$\rightarrow$\>
\nonterm/{note}:\nonterm/{mode}\\

\nextrule/\>\nonterm/{mode}\>$\rightarrow$\>
\term/{\lslmajor/} \\
\>\>\>\myalt/ \term/{\lslminor/} \\
\>\>\>\myalt/ \term/{\lsllydian/} \\
\>\>\>\myalt/ \term/{\lslionian/} \\
\>\>\>\myalt/ \term/{\lslmixolydian/} \\
\>\>\>\myalt/ \term/{\lsldorian/} \\
\>\>\>\myalt/ \term/{\lslaeolian/} \\
\>\>\>\myalt/ \term/{\lslphrygian/} \\
\>\>\>\myalt/ \term/{\lsllocrian/}\\

\nextrule/\>\nonterm/{user-defined}\>$\rightarrow$\>
(\nonterm/{note-sequence})\\

\nextrule/\>\nonterm/{time-sig}\>$\rightarrow$\>
(\nonterm/{beat-structure} : \term/{\lslint/})\\

\nextrule/\>\nonterm/{beat-structure}\>$\rightarrow$\>
\nonterm/{beat-structure} + \term/{\lslint/}\\
\>\>\>\myalt/ \term/{\lslint/}\\

\nextrule/\>\nonterm/{filename}\>$\rightarrow$\> \term/{char}$^+$\\

\nextrule/\>\nonterm/{function-name}\>$\rightarrow$\> \term/{char}$^+$\\

\nextrule/\>\nonterm/{tagged-value-list} \>$\rightarrow$\>
\nonterm/{tagged-value-list} \nonterm/{tagged-value}\\

\nextrule/\>\nonterm/{tagged-value}\>$\rightarrow$\>
\nonterm/{play-attribute-tag} = \nonterm/{constant}\\

\nextrule/\>\nonterm/{play-attribute-tag}\>$\rightarrow$\>
\term/{\lslchan/} \myalt/  \term/{\lslplay/} \myalt/  
\term/{\lslinst/} \myalt/ 
\term/{\lslmm/} \myalt/ \term/{\lslmm/} \nonterm/{mmspec}\\

\end{tabbing}


\item Interpretation of a string
is context dependent. Thus, for example,
when assigned to a variable of type
\lslpattern/, 
the string ``.cmajor C5''  denotes a sequence of notes
consisting  of the value of the variable .cmajor followed by
the note C5. The same string when used
in the context \lslfile/ = ``.cmajor C5'' denotes
a file name .cmajor C5. Notes enclosed in parentheses
such as in ``G3 (C4E4G4) C5'' are treated as 
forming a blocked chord. The string ``hello'' 
results in an invalid assignment command 
when it appears on the right side of an assignment 
to a variable of type \lslpattern/.

\item Ambiguity may arise while
defining a note
sequence such as in ``cbb''. To avoid this,
the notes may be separated by at least
one space character such as in ``cb b''.

\item The grammar above contains some terminals
prefixed by {\bf l-}. Such terminals denote
language specific constructs.
A complete list of such terminals appears
in Table~\ref{lang-dep-terminals}.
These terminal symbols may be  nonterminals
or terminals in the grammar of the language $L$
of the auralized program. The LSL preprocessor
attempts to parse over the strings corresponding
to such symbols. These strings are parsed by the
compiler for $L$.


\end{enumerate}


\begin{table}
\centering
\caption{Language Dependent Terminals in LSL Grammar.}
\label{lang-dep-terminals}
\begin{tabular}{|l|p{2in}|p{1.5in}|}
\mc{3}{l}{\tablestrut}\\
\hline
\mc{1}{|c|}{{\bf Terminal}}&\mc{1}{c|}{{\bf Meaning}}
&\mc{1}{c|}{{\bf Example from C}}\\
\hline
\tablestrut&&\\
\term/{l-condition}&Conditional expression which evaluates
to {\em true} or {\em false}.& ($x<y~\myand/~p>q$)\\
\term/{l-id}&Identifier& {\em drag\_icon}\\
\term/{l-expression}&An expression that evaluates to
a value of type  matching the type
of the left side of the assignment in which it appears.&
($min-val * 2$)\\
\term/{\langdep/{function}}&A function  invoked for
tracking one or more variables.&
Any C function definition.\\
\term/{\langdep/{actual-parameter-list}}&List of
actual parameters. & \lslint/ x, \lslint/ * y\\
\hline
\end{tabular}
\end{table}



\section{Static Semantics}

The following constraints  apply to 
LSL specifications. These are not indicated by the
syntax.

\begin{enumerate}

\item All identifiers must be declared before use.
Identifiers that belong to the auralized program  must
appear as \lslexternal/s. 


\item  Local attribute values, 
such as metronome values, channels, etc. which are 
specified explicitly as attributes, 
take precedence over  corresponding global values.
However, they do not alter the global values.
Global values of such parameters may be set
using the \lslset/ command within an LSL specification
or in the program.


\item Identifiers declared within  a \lslspecmod/ $M$ 
are global to $M$ and may be used by all
\lslspecdef/s declared within $M$.
Identifiers declared within a
\lslspecdef/ $S$ are local
to $S$ and may not be used by other \lslspecdef/s
or in any other \lslspecmod/. Identifiers may
be exported by an \lslspecmod/ for
use by any other module by explicitly 
mentioning it in an \lslexport/ declaration.
A module may use an identifier exported by another module
by explicitly importing it using the \lslimport/ 
declaration. All program variables used
in an \lslspecdef/ or a \lslspecmod/ body must
be specified as \lslexternal/s.
Program identifiers, global to a VDAP definition,
need  not be declared. However,
all such identifiers must be declared in
the context wherein VDAP will 
be placed and compiled by the C compiler.



\item A VDAP specification must be a valid
C function when using  LSL/C. 

\item The formal and actual parameters
must match in number and type 
between  a specification definition and 
its use. 


\item All matching \lslbegin/s and \lslend/s  must match 
in the identifiers that follow the corresponding keyword.
Thus, for example, a \lslbegin/~gear which
matches with an
\lslend/~change will be flagged as a warning 
because {\em gear} and {\em change} do not match.

\item LSL has default values for
various parameters such as metronome,
channel, and  instrument. 


\item The {\em expression} in a
relative timed event must
evaluate to a positive integer or else a run time
warning is issued.
A relative timed event is ignored if it occurs after
program execution terminates.


\item A file or function specified in
a scope tag must exist for the 
program to be auralized.

\item While monitoring an activity or data,
tracking will terminate upon program termination
if the start event occurs 
after the terminating event.



\item An {\em expression}  in a 
{\em range-list} must evaluate to an integer
and must not contain any variable names.
Subscript expressions that evaluate to a value
outside the specified range
are not allowed.

\item If both the initial value and the capture location
are specified for a variable to
be tracked, LSL will attempt to 
satisfy both requirements.
Thus, the variable will
be initialized  at an appropriate point
during  program  execution. Its value will
also be captured as specified. The value 
captured will override any previous value of the variable.


\item The syntax of LSL allows for the naming of
any command. However, only names of \lslnotify/,
\lsltrack/, and \lslatrack/ correspond to
classes. Naming of other commands is permitted
to allow referencing of commands while
editing or reading an LSL specification.



\item Use of \lsltoggle/ may give rise to ambiguities at run time.
For example, if the space key on the
computer keyboard has been specified
as a toggle source and the executing program requests for 
input data, it is not clear if the  space  character
should be treated as a toggle  request
or input to the program. The user
may avoid such ambiguities by selecting
a toggle source that will
not be required as input to
the program. Alternately, the user may rely
on the run time window based monitor to
input toggle requests.


\end{enumerate}

