Commit 2ccdb77c authored by Dmitry.Shahtanov's avatar Dmitry.Shahtanov Committed by Alexander.Trofimov

Добавлен генератор парсеров, грамматика Excel-формул, визуализатор грамматик.

git-svn-id: svn://192.168.3.15/activex/AVS/Sources/TeamlabOffice/trunk/OfficeWeb@59496 954022d7-b5bf-4e40-9824-e11837661b57
parent 118ec71c
logic = "TRUE" | "FALSE".
numConst = DecimalIntegerLiteral "." {decDig} {ExponentPart} | "." decDig {ExponentPart} | DecimalIntegerLiteral {ExponentPart}.
DecimalIntegerLiteral = "0" | NonZeroDigit {decDig}.
NonZeroDigit = {[+-]}[1-9].
ExponentPart = "e"i SignedInteger.
SignedInteger = {[+-]}decDig.
digSeq = decDig {decDig}.
decDig = [0-9].
Java = ["package" Name ";"]
{"import" Name ["." "*"] ";"}
{ClassDecl | InterfaceDecl | ";"}.
ClassDecl = {Modifyer} "class" ident
["extends" Name]
["implements" Name {"," Name} ]
"{" { FieldDecl
| MethodDecl
| ConstructorDecl
| "static" Block
}
"}".
InterfaceDecl = {Modifyer} "interface" ident
["extends" Name {"," Name} ]
"{" { FieldDecl
| MethodHeader ";"
}
"}".
FieldDecl = {Modifyer} Type Var {"," Var} ";".
Var = ident {"[" "]"} ["=" VarInit].
VarInit = Expr | ArrayInit.
ArrayInit = "{" VarInit {"," VarInit} "}".
MethodDecl = MethodHeader (Block | ";").
MethodHeader = {Modifyer} (Type | "void") ident "(" [FormPars] ")"
{"[" "]"}
["throws" Name {"," Name} ].
FormPars = FormPar {"," FormPar}.
FormPar = Type ident {"[" "]"}.
ConstructorDecl = {Modifyer} ident "(" [FormPars] ")"
["throws" Name {"," Name} ]
"{" [ConstructorCall] {BlockStatement} "}".
ConstructorCall = ("this" | "super") "(" [ActPars] ")".
Modifyer = "public" | "protected" | "private"
| "static"
| "abstract" | "final" | "native" | "synchronized" |
"transient" | "volatile".
Block = "{" {BlockStatement} "}".
BlockStatement = Type Var {"," Var} ";"
| Statement.
Statement = {ident ":"}
( Block
| [StatExpr] ";"
| "if" "(" Expr ")" Statement ["else" Statement]
| "while" "(" Expr ")" Statement
| "for" "(" [ForInit] ";" [Expr] ";" [ForUpdate] ")"
Statement
| "do" Statement "while" "(" Expr ")" ";"
| "switch" "(" Expr ")" "{" {SwitchGroup}
{SwitchLabel} "}"
| "break" [ident] ";"
| "continue" [ident] ";"
| "return" [Expr] ";"
| "synchronized" "(" Expr ")" Block
| "throw" Expr ";"
| "try" Block {CatchClause} ["finally" Block]
).
StatExpr = Assignment
| Designator "(" [ActPars] ")"
| Expr.
SwitchGroup = SwitchLabel {SwitchLabel} BlockStatement
{BlockStatement}.
SwitchLabel = "case" ConstExpr ":" | "default" ":".
ForInit = StatExpr {"," StatExpr}
| Type Var {"," Var} ";".
ForUpdate = StatExpr {"," StatExpr}.
CatchClause = "catch" "(" FormPar ")" Block.
ConstExpr = Expr.
Expr = CondExpr | Assignment.
CondExpr = CondOrExpr ["?" Expr ":" CondExpr].
CondOrExpr = CondAndExpr {"||" CondAndExpr}.
CondAndExpr = OrExpr {"&&" OrExpr}.
OrExpr = XorExpr {"|" XorExpr}.
XorExpr = AndExpr {"^" AndExpr}.
AndExpr = EqualExpr {"&" EqualExpr}.
EqualExpr = RelExpr {("==" | "!=") RelExpr}.
RelExpr = ShiftExpr {("<" | ">" | "<=" | ">=") ShiftExpr}
| ShiftExpr "instanceof" RefType.
ShiftExpr = AddExpr {("<<" | ">>" | ">>>") AddExpr}.
AddExpr = MulExpr {("+" | "-") MulExpr}.
MulExpr = Unary {("*" | "/" | "%") Unary}.
Unary = {"+" | "-" | "++" | "--" | "!" | "~"} Primary {"++" | "--"}.
Primary =
( Literal
| ident
| "this"
| "super"
| "(" Expr ")"
| "(" Type ")" Primary
| "new" ( PrimitiveType "[" Expr "]"
| Name ( "[" Expr "]" |
"(" [ActPars] ")" )
)
)
{ "." ident
| "[" [Expr] "]"
| "(" [ActPars] ")"
}.
ActPars = Expr {"," Expr}.
Assignment = Designator AssignOp Expr.
Designator = (ident | "this" | "super") {"." ident | "[" Expr "]"}.
AssignOp = "=" | "*=" | "/=" | "+=" | "-=" | "<<=" | ">>=" |
">>>="
| "&=" | "^=" | "|=".
Type = (PrimitiveType | Name) {"[" "]"}.
PrimitiveType = "byte " | "short" | "int" | "long" | "char"
| "float"| "double"
| "boolean".
RefType = Name {"[" "]"}
| PrimitiveType "[" "]" {"[" "]"}.
Name = {ident "."} ident.
Literal = number | string | char.
\ No newline at end of file
Ident = letter { letter | digit } .
QualIdent = { Ident "." } Ident .
Number = Integer | Real .
Integer = DecInteger | OctInteger | HexInteger .
DecInteger = digit { digit } .
OctInteger = ( "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" )
{ "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" } "B" .
HexInteger = digit { digit | "A" | "B" | "C" | "D" | "E" | "F" } "H" .
Real = digit { digit } "." { digit }
[ "E" [ "+" | "-" ] digit { digit } ] .
String = "'" { character } "'" | '"' { character } '"' | OctChar .
OctChar = ( "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" )
{ "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" } "C" .
ProgramModule = "MODULE" Ident [ Priority ] ";"
{ Import } Block "END" Ident "." .
Block = { Declaration } [ BEGIN StatementSequence ] .
Declaration = CONST { ConstDeclaration }
| TYPE { TypeDeclaration }
| VAR { VariableDeclaration }
| ProcedureDeclaration
| ModuleDeclaration .
StatementSequence = Statement { ";" Statement } .
Enumeration = "(" Ident { "," Ident } ")" .
Subrange = [ QualIdent ] "[" ConstExpr ".." ConstExpr "]" .
SetType = SET OF SimpleType .
SimpleType = QualIdent | Enumeration | Subrange .
ArrayType = ARRAY SimpleType { "," SimpleType } OF Type .
RecordType = "RECORD" FieldList { ";" FieldList } "END" .
FieldList = [ Ident { "," Ident } ":" Type
| VariantFieldList ] .
VariantFieldList = CASE [ Ident ] ":" QualIdent OF
( Variant { "|" Variant }
[ ELSE FieldList { ";" FieldList } ] END ) .
Variant = [ CaseLabelList ":" FieldList { ";" FieldList } ] .
CaseLabelList = ConstExpr [ ".." ConstExpr ]
{ "," ConstExpr [ ".." ConstExpr ] } .
PointerType = "POINTER" "TO" Type .
ConstantDeclaration = Ident "=" ConstExpr ";" .
ConstExpr = Expression .
TypeDeclaration = Ident "=" type .
Type = SetType | SimpleType | ArrayType | RecordType
| PointerType | ProcedureType .
VariableDeclaration = Ident { "," Ident } ":" Type ";" .
Designator = QualIdent { "^" | "." ident
| "[" Expression {"," Expression } "]" } .
Expression = SimpleExpression [ Relation SimpleExpression ] .
Relation = "="|"<>"|"#"|"<"|"<="|">"|">="|"IN".
SimpleExpression = [ "+" | "-" ] Term { ( "+" | "-" | "OR" ) Term } .
Term = Factor { MulOperator Factor } .
MulOperator = "*" | "/" | "DIV" | "MOD" | "AND" | "&" .
Factor = Designator [ "(" [ Expression { "," Expression } ] ")" ]
| Number
| String
| Set
| "(" expression ")"
| ( "NOT" | "~" ) Factor.
Set = [ QualIdent ] "{" [ Element { "," Element } ] "}" .
Element = Expression [ ".." Expression ] .
Statement = [ Assignment | IfStatement | CaseStatement |
WhileStatement | RepeatStatement | ForStatement | LoopStatement |
ExitStatement | WithStatement | ProcedureCall | ReturnStatement ] .
Assignment = Designator ":=" Expression .
IfStatement = "IF" Expression "THEN" StatementSequence
{ "ELSIF" Expression "THEN" StatementSequence }
[ "ELSE" StatementSequence ] "END" .
CaseStatement = "CASE" expression "OF"
[ CaseLabelList ":" StatementSequence ]
{ "|" [CaseLabelList ":" StatementSequence ] }
[ "ELSE" StatementSequence ] "END" .
WhileStatement = "WHILE" Expression "DO" StatementSequence "END" .
RepeatStatement = "REPEAT" StatementSequence "UNTIL" Expression .
ForStatement = "FOR" Ident ":=" Expression "TO" Expression
[ "BY" ConstExpression]
( "DO" StatementSequence "END" ) .
LoopStatement = "LOOP" StatementSequence "END" .
ExitStatement = "EXIT".
WithStatement = "WITH" Designator "DO" StatementSequence "END" .
ProcedureDeclaration = ProcedureHeading Block END Ident ";" .
ProcedureHeading = "PROCEDURE" ident [ FormalParameters ] ";" .
FormalParameters = "(" [ ParamSection { ";" ParamSection } ] ")"
[ ":" QualIdent ] .
ParamSection = [ "VAR" ] Ident { "," Ident } ":" FormalType .
FormalType = [ "ARRAY" "OF" ] QualIdent .
ProcedureCall = Designator [ "(" [ Expression {"," Expression} ] ")" ] .
ReturnStatement = RETURN [ Expression ] .
ProcedureType = "PROCEDURE" [ FormalTypeList ].
FormalTypeList = "(" [ [ "VAR" ] FormalType
{ "," [ "VAR" ] FormalType } ] ")" [ ":" QualIdent ] .
ModuleDeclaration = "MODULE" Ident [ Priority ] ";"
( { Import } [ Export ] )
Block "END" Ident ";" .
Import = [ "FROM" ident ] "IMPORT" Ident { "," Ident } ";" .
Export = "EXPORT" [ "QUALIFIED" ] Ident { "," Ident } ";" .
DefinitionModule = "DEFINITION" "MODULE" Ident ";"
{ Import } { Definition } "END" Ident "." .
Definition = "CONST" { ConstantDeclaration }
| "TYPE" { TypeDefinition }
| "VAR" { VariableDeclaration }
| ProcedureHeading.
TypeDefinition = Ident [ "=" Type ] ";" .
ImplementationModule = "IMPLEMENTATION" ProgramModule .
TypeTransfer = QualIdent "(" Expression ")" .
Priority = "[" ConstExpression "]" .
\ No newline at end of file
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>EBNF-Visualizer - Manual</title>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Pragma" content="no-cache">
<meta content="EBNF, GIF, Visualizer, Grafik, Syntax, Diagramm" name="keywords">
</head>
<body>
<h1>EBNF Visualizer - Manual</h1>
<h2>Content</h2>
<a href="#Introduction"> Introduction </a><br>
<a href="#Simple"> Simple example </a><br>
<a href="#EBNF"> EBNF - Extended Backus Naur Form</a><br>
<a href="#Writing"> Writing an .ebnf-file </a><br>
<a href="#Menu"> Menu </a><br>
<a href="#Functions"> Functions </a><br>
<a href="#License"> License & Copyright </a><br>
<a href="#Contact"> Contact </a><br>
<h2><a name="Introduction">Introduction</a></h2>
This program visualizes EBNF (Extended Backus Naur Form). Therefore an .ebnf File is required, which contains rules written in EBNF. The program parses the rules, visualizes them in form of syntax diagrams and is able to generate .gif files for further use. Furthermore the program allows to manipulate the look of the generated syntax diagrams.
<h2><a name="Simple">Simple example</a></h2>
<h3>Step 1:</h3>
Create a .ebnf file with a rule just like “A= a [b] c.”. A .ebnf file is just a simple .txt file, just change the ending of the file.
<h3>Step 2:</h3>
Start the program and open the .ebnf file via the menu entry “Load Grammar…”. The program parses it. If there exist errors in the .ebnf file, it would be reported in the log window. Otherwise the rule menu will be activated.<p><img src="open.JPG" alt="Open a .ebnf file">
<h3>Step 3:</h3>
Choose a rule from the loaded grammar in the rule menu. The chosen rule will be drawn.
<p><img src="choose.JPG" alt="Chose a rule">
<h3>Step 4 (optional):</h3>
Change the look of the syntax diagram in the menu File/Settings.
<p><img src="settings.JPG" alt="Settings">
<h3>Step 5 (optional):</h3>
Save the syntax diagram or just copy/paste it.
<h2><a name="EBNF">EBNF - Extended Backus Naur Form</a></h2>
EBNF is used to define the grammar of programming languages.
<br>Therefore a set of rules is specified. These are known as production rules.
They define the patterns or sequences of symbols allowed in the language. Each production rule defines the pattern that represents a named structured part of the language, such as an expression or a statement.
The name of such a part is called a non-terminal symbol in the language. The basic building blocks of the language are symbols which stand for themselves.
These can be individual characters or combinations such as keywords and arithmetic operators. These basic elements of the language are called terminal symbols.
<h2><a name="Writing">Writing an .ebnf-file</a></h2>
The following description is informal but will allow you to write EBNF that works with this program.<p>
A grammar consists of a set of rules. A rule consist of an identifier, followed by “=”, a sequence of meta, terminal and nonterminal symbols and ends with “.” (e.g. “A= a b [c].”)
<h3>Terminal symbol:</h3>
A terminal symbol can be any string. They are separated by space characters. <br>For example in the rule “A = a b [c].” a, b and c are terminal symbols.
<p><img src="terminal.GIF" alt="Simple example"><p>
It is also possible to put a terminal symbol under quotes (“) or apostrophes (‘) which is required in some cases.
(eg. Quote = "'" a "'".)<p>
<img src="Quote.GIF" alt="Simple example"><p>It’s also needed for numbers, because identifiers must begin with a character.
<h3>Nonterminal symbol:</h3>
A nonterminal symbol can’t be created in an explicit way.<br>If a terminal symbol matches the string of an rule identifier, it is automatically considered as a nonterminal symbol.<br>
For example, in the rule “A = a A | b.” A is a nonterminal symbol.
<p><img src="nonterminal.GIF" alt="Simple example">
<h3>Meta symbols:</h3>
<h4>- option “[“ “]”</h4>
The sequence of symbols within these brackets are optional.<br>
(e.g. Rule1 = “begin [optional things] end.”)
<p><img src="Rule1.GIF" alt="Simple example">
<h4>-iteration “{“ “}”</h4>
The sequence of symbols within these brackets can occur from zero to infinite times.<br>
(e.g. Rule2 = “begin {and again} end.”)
<p><img src="Rule2.GIF" alt="Simple example">
<h4>-alternative “|”</h4>
It allows to choose a sequence of symbols.<br>
(e.g. Rule3 = “I am a (good | bad) programmer.”)
<p><img src="Rule3.GIF" alt="Simple example">
<h4>-grouping “(“ “)”</h4>
These brackets are used to group sequences of symbols in a mathematical way.
<h3>Special symbol – Line break:</h3>
This program allows to make explicit line breaks within a syntax diagram. To do this, use “\n” in the outer structure of the rule. That means, it will be ignored within an option, iteration or alternative.<br>
(e.g. “Linebreak = First line \n Second line \n End.”)
<p><img src="Linebreak.GIF" alt="Simple example">
<h2><a name="Menu">Menu</a></h2>
<p><img src="open.JPG" alt="Menu">
<h3>File:</h3>
<h4>Load Grammar… :</h4>
Allows to load a grammar file (*.ebnf).
<h4>Save As… :</h4>
The current rule can be stored as .GIF file.
<h4>Copy:</h4>
The current rule is copied to the clipboard as a picture. It is possible to paste it into any program which allows to paste from the clipboard.
<h4>Settings… :</h4>
<p><img src="settings.JPG" alt="Settings"><br>
In the menu settings the look of the syntax diagrams can be changed.
<h5>Font</h5>
Change the font of terminal and nonterminal symbols.
<h5>Line</h5>
Change the thickness and the color of the line. It is also possible to increase or decrease the size of the arrows.
<h5>Dimensions</h5>
It is possible to increase or decrease the horizontal and vertical gap between the symbols.
The look of the terminal and nonterminal symbols can be changed by increasing or decreasing the gap between the line of the symbol and its name.
<h5>Optimizations</h5>
If the checkbox "Enable optimizations" is activated, the syntaxgraph will be optimized. Any change of this option requires to reload the actual grammar.
<h2><a name="Functions">Functions</a></h2>
<h3>Optimizations:</h3>
This happens implicitly. It is possible to disable them in the settings menu.<br>
If the syntax graph is optimized, redundant und needless productions within a rule are deleted. That means empty nodes, iterations, options and alternatives are removed. If there is an empty alternative, it is moved to the first position. Already existing alternatives are removed.
Furthermore some productions are visualized in a more elegant way,
<br> for example “A = ab {ab}.”
<p><img src="optimize1not.GIF" alt="Optimize"><img src="optimize1.GIF" alt="Optimize"><p>
or “B = ab { cd ab}.”
<p><img src="optimize2not.GIF" alt="Optimize"><img src="optimize2.GIF" alt="Optimize"><p>
<h2><a name="License">License & Copyright</a></h2>
EBNF Visualizer<br>
Copyright (c) 2005 Stefan Schoergenhumer, Markus Dopler<br>
supported by Hanspeter Moessenboeck, University of Linz<br>
<p>
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
<p>
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
<p>
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
<h2><a name="Contact">Contact</a></h2>
For further questions, please write an Email to:<p>
Markus Dopler, k0156207@students.jku.at or<br>
Stefan Schörgenhumer, k0155531@students.jku.at
</body>
</html>
COMPILER EBNF
CHARACTERS
letter = 'A'..'Z' + 'a'..'z' + '_'.
digit = '0'..'9'.
importantascii = ' '..'~' .
noquote = importantascii - '"'.
noapostrophe = importantascii - '\''.
TOKENS
ident = letter {letter | digit}.
terminal = '"' {noquote} '"' | '\'' {noapostrophe} '\''.
wrap = '\\' 'n'.
IGNORE '\t' + '\r' + '\n'
PRODUCTIONS
EBNF
= Rule
{Rule}.
Rule
= ident (. Node n;
Symbol s=Symbol.Find(t.val); //look if already known
if(s==null) n=new Node(new Symbol(Node.nt,t.val));
else {
if(s.typ==Node.nt) {
String message="ERROR: Nonterminal symbol "+t.val+" has been defined multiple times.";
EbnfForm.WriteLine(message);
n=new Node(new Symbol(0,"BUG"));
} else { //if only considered as terminal symbol until now
s.typ=Node.nt;
Symbol.terminalToNt(s.name);
Symbol.terminalToNt(s.name);
Node.terminalToNt(s.name);
n=Node.Find(s.name);
}
}
.)
"="
Expr <out n.sym.graph>
"."
(. Graph.Finish(n.sym.graph); .)
.
Expr <out Graph g>
= (. Graph g1; .)
Alt <out g>
(. bool first = true; .)
{ '|'
Alt <out g1>
(. if (first) { Graph.MakeFirstAlt(g); first = false; }
Graph.MakeAlternative(g, g1);
.)
}
.
Alt <out Graph g>
=
(. Graph g1; g=new Graph(); .)
{Sym <out g1>
(. Graph.MakeSequence(g, g1); .)
}
(. if(g.l==null && g.r==null)
g=new Graph(new Node(Node.eps,null));
.)
.
Sym <out Graph g>
(. Graph g1;g=new Graph(); .)
=
ident (. Symbol s=Symbol.Find(t.val);
Node n;
if(s!=null) n= new Node(s);
else n=new Node(new Symbol(Node.t,t.val)); //type could be nt, but not known yet
g=new Graph(n);
.)
| terminal (.
char[] trim=new char[1];
trim[0]=t.val[0];
String temp=t.val.Trim(trim);
Node n =new Node(new Symbol(Node.t,temp));
g=new Graph(n);
.)
| wrap (.
Node n =new Node(Node.wrap,null);
g=new Graph(n);
.)
| '(' Expr <out g1>')'
(. g=g1; .)
| '[' Expr <out g1>']'
(. Graph.MakeOption(g1);
g=g1;
.)
| '{' Expr <out g1>'}'
(. Graph.MakeIteration(g1);
g=g1;
.)
.
END EBNF.
Scanner.cs and Parser.cs have been generated by the Compiler Generator Coco/R.
The file EBNF.ATG contains the attributed grammar for the Coco.
See: http://www.ssw.uni-linz.ac.at/Research/Projects/Coco/
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
/*-------------------------------------------------------------------------
EBNF Visualizer
Copyright (c) 2005 Stefan Schoergenhumer, Markus Dopler
supported by Hanspeter Moessenboeck, University of Linz
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
This class has been generated by the Compiler Generator Coco/R.
See: http://www.ssw.uni-linz.ac.at/Research/Projects/Coco/
-------------------------------------------------------------------------*/
using System;
public class Parser {
const int _EOF = 0;
const int _ident = 1;
const int _terminal = 2;
const int _wrap = 3;
const int maxT = 13;
const bool T = true;
const bool x = false;
const int minErrDist = 2;
public static Token t; // last recognized token
public static Token la; // lookahead token
static int errDist = minErrDist;
static void SynErr (int n) {
if (errDist >= minErrDist) Errors.SynErr(la.line, la.col, n);
errDist = 0;
}
public static void SemErr (string msg) {
if (errDist >= minErrDist) Errors.Error(t.line, t.col, msg);
errDist = 0;
}
static void Get () {
for (;;) {
t = la;
la = Scanner.Scan();
if (la.kind <= maxT) { ++errDist; break; }
la = t;
}
}
static void Expect (int n) {
if (la.kind==n) Get(); else { SynErr(n); }
}
static bool StartOf (int s) {
return set[s, la.kind];
}
static void ExpectWeak (int n, int follow) {
if (la.kind == n) Get();
else {
SynErr(n);
while (!StartOf(follow)) Get();
}
}
static bool WeakSeparator (int n, int syFol, int repFol) {
bool[] s = new bool[maxT+1];
if (la.kind == n) { Get(); return true; }
else if (StartOf(repFol)) return false;
else {
for (int i=0; i <= maxT; i++) {
s[i] = set[syFol, i] || set[repFol, i] || set[0, i];
}
SynErr(n);
while (!s[la.kind]) Get();
return StartOf(syFol);
}
}
static void EBNF() {
Rule();
while (la.kind == 1) {
Rule();
}
}
static void Rule() {
Expect(1);
Node n;
Symbol s=Symbol.Find(t.val); //look if already known
if(s==null) n=new Node(new Symbol(Node.nt,t.val));
else {
if(s.typ==Node.nt) {
String message="ERROR: Nonterminal symbol "+t.val+" has been defined multiple times.";
EbnfForm.WriteLine(message);
n=new Node(new Symbol(0,"BUG"));
} else { //if only considered as terminal symbol until now
s.typ=Node.nt;
Symbol.terminalToNt(s.name);
Symbol.terminalToNt(s.name);
Node.terminalToNt(s.name);
n=Node.Find(s.name);
}
}
Expect(4);
Expr(out n.sym.graph);
Expect(5);
Graph.Finish(n.sym.graph);
}
static void Expr(out Graph g) {
Graph g1;
Alt(out g);
bool first = true;
while (la.kind == 6) {
Get();
Alt(out g1);
if (first) { Graph.MakeFirstAlt(g); first = false; }
Graph.MakeAlternative(g, g1);
}
}
static void Alt(out Graph g) {
Graph g1; g=new Graph();
while (StartOf(1)) {
Sym(out g1);
Graph.MakeSequence(g, g1);
}
if(g.l==null && g.r==null)
g=new Graph(new Node(Node.eps,null));
}
static void Sym(out Graph g) {
Graph g1;g=new Graph();
switch (la.kind) {
case 1: {
Get();
Symbol s=Symbol.Find(t.val);
Node n;
if(s!=null) n= new Node(s);
else n=new Node(new Symbol(Node.t,t.val)); //type could be nt, but not known yet
g=new Graph(n);
break;
}
case 2: {
Get();
char[] trim=new char[1];
trim[0]=t.val[0];
String temp=t.val.Trim(trim);
Node n =new Node(new Symbol(Node.t,temp));
g=new Graph(n);
break;
}
case 3: {
Get();
Node n =new Node(Node.wrap,null);
g=new Graph(n);
break;
}
case 7: {
Get();
Expr(out g1);
Expect(8);
g=g1;
break;
}
case 9: {
Get();
Expr(out g1);
Expect(10);
Graph.MakeOption(g1);
g=g1;
break;
}
case 11: {
Get();
Expr(out g1);
Expect(12);
Graph.MakeIteration(g1);
g=g1;
break;
}
default: SynErr(14); break;
}
}
public static void Parse() {
la = new Token();
la.val = "";
Get();
EBNF();
Expect(0);
}
static bool[,] set = {
{T,x,x,x, x,x,x,x, x,x,x,x, x,x,x},
{x,T,T,T, x,x,x,T, x,T,x,T, x,x,x}
};
} // end Parser
public class Errors {
public static int count = 0; // number of errors detected
public static string errMsgFormat = "-- line {0} col {1}: {2}"; // 0=line, 1=column, 2=text
public static void SynErr (int line, int col, int n) {
string s;
switch (n) {
case 0: s = "EOF expected"; break;
case 1: s = "ident expected"; break;
case 2: s = "terminal expected"; break;
case 3: s = "wrap expected"; break;
case 4: s = "\"=\" expected"; break;
case 5: s = "\".\" expected"; break;
case 6: s = "\"|\" expected"; break;
case 7: s = "\"(\" expected"; break;
case 8: s = "\")\" expected"; break;
case 9: s = "\"[\" expected"; break;
case 10: s = "\"]\" expected"; break;
case 11: s = "\"{\" expected"; break;
case 12: s = "\"}\" expected"; break;
case 13: s = "??? expected"; break;
case 14: s = "invalid Sym"; break;
default: s = "error " + n; break;
}
Console.WriteLine(Errors.errMsgFormat, line, col, s);
EbnfForm.WriteLine("ERROR: Line: "+line+" Col: "+ col+": "+ s);
count++;
}
public static void SemErr (int line, int col, int n) {
Console.WriteLine(errMsgFormat, line, col, ("error " + n));
count++;
}
public static void Error (int line, int col, string s) {
Console.WriteLine(errMsgFormat, line, col, s);
count++;
}
public static void Exception (string s) {
Console.WriteLine(s);
System.Environment.Exit(1);
}
} // Errors
/*-------------------------------------------------------------------------
EBNF Visualizer
Copyright (c) 2005 Stefan Schoergenhumer, Markus Dopler
supported by Hanspeter Moessenboeck, University of Linz
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
This class has been generated by the Compiler Generator Coco/R.
See: http://www.ssw.uni-linz.ac.at/Research/Projects/Coco/
-------------------------------------------------------------------------*/
using System;
using System.IO;
using System.Collections;
using System.Text;
public class Token {
public int kind; // token kind
public int pos; // token position in the source text (starting at 0)
public int col; // token column (starting at 0)
public int line; // token line (starting at 1)
public string val; // token value
public Token next; // AW 2003-03-07 Tokens are kept in linked list
}
public class Buffer {
public const char EOF = (char)256;
static byte[] buf;
static int bufLen;
static int pos;
public static void Fill (Stream s) {
bufLen = (int) s.Length;
buf = new byte[bufLen];
s.Read(buf, 0, bufLen);
pos = 0;
}
public static int Read () {
if (pos < bufLen) return buf[pos++];
else return EOF; /* pdt */
}
public static int Peek () {
if (pos < bufLen) return buf[pos];
else return EOF; /* pdt */
}
/* AW 2003-03-10 moved this from ParserGen.cs */
public static string GetString (int beg, int end) {
StringBuilder s = new StringBuilder(64);
int oldPos = Buffer.Pos;
Buffer.Pos = beg;
while (beg < end) { s.Append((char)Buffer.Read()); beg++; }
Buffer.Pos = oldPos;
return s.ToString();
}
public static int Pos {
get { return pos; }
set {
if (value < 0) pos = 0;
else if (value >= bufLen) pos = bufLen;
else pos = value;
}
}
}
public class Scanner {
const char EOL = '\n';
const int eofSym = 0; /* pdt */
const int charSetSize = 256;
const int maxT = 13;
const int noSym = 13;
static short[] start = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 2, 0, 0, 0, 0, 3, 10, 11, 0, 0, 0, 0, 8, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 5, 13, 0, 1,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 14, 9, 15, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-1};
static Token t; // current token
static char ch; // current input character
static int pos; // column number of current character
static int line; // line number of current character
static int lineStart; // start position of current line
static int oldEols; // EOLs that appeared in a comment;
static BitArray ignore; // set of characters to be ignored by the scanner
static Token tokens; // the complete input token stream
static Token pt; // current peek token
public static void Init (string fileName) {
FileStream s = null;
try {
s = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
Init(s);
} catch (IOException) {
EbnfForm.WriteLine("--- Cannot open file "+ fileName);
//System.Environment.Exit(1);
} finally {
if (s != null) s.Close();
}
}
public static void Init (Stream s) {
Buffer.Fill(s);
pos = -1; line = 1; lineStart = 0;
oldEols = 0;
NextCh();
ignore = new BitArray(charSetSize+1);
ignore[' '] = true; // blanks are always white space
ignore[9] = true; ignore[10] = true; ignore[13] = true;
//--- AW: fill token list
tokens = new Token(); // first token is a dummy
Token node = tokens;
do {
node.next = NextToken();
node = node.next;
} while (node.kind != eofSym);
node.next = node;
node.val = "EOF";
t = pt = tokens;
}
static void NextCh() {
if (oldEols > 0) { ch = EOL; oldEols--; }
else {
ch = (char)Buffer.Read(); pos++;
// replace isolated '\r' by '\n' in order to make
// eol handling uniform across Windows, Unix and Mac
if (ch == '\r' && Buffer.Peek() != '\n') ch = EOL;
if (ch == EOL) { line++; lineStart = pos + 1; }
}
}
static void CheckLiteral() {
switch (t.val) {
default: break;
}
}
/* AW Scan() renamed to NextToken() */
static Token NextToken() {
while (ignore[ch]) NextCh();
t = new Token();
t.pos = pos; t.col = pos - lineStart + 1; t.line = line;
int state = start[ch];
StringBuilder buf = new StringBuilder(16);
buf.Append(ch); NextCh();
switch (state) {
case -1: { t.kind = eofSym; goto done; } // NextCh already done /* pdt */
case 0: { t.kind = noSym; goto done; } // NextCh already done
case 1:
if ((ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'Z' || ch == '_' || ch >= 'a' && ch <= 'z')) {buf.Append(ch); NextCh(); goto case 1;}
else {t.kind = 1; goto done;}
case 2:
if ((ch >= ' ' && ch <= '!' || ch >= '#' && ch <= '~')) {buf.Append(ch); NextCh(); goto case 2;}
else if (ch == '"') {buf.Append(ch); NextCh(); goto case 4;}
else {t.kind = noSym; goto done;}
case 3:
if ((ch >= ' ' && ch <= '&' || ch >= '(' && ch <= '~')) {buf.Append(ch); NextCh(); goto case 3;}
else if (ch == 39) {buf.Append(ch); NextCh(); goto case 4;}
else {t.kind = noSym; goto done;}
case 4:
{t.kind = 2; goto done;}
case 5:
if (ch == 'n') {buf.Append(ch); NextCh(); goto case 6;}
else {t.kind = noSym; goto done;}
case 6:
{t.kind = 3; goto done;}
case 7:
{t.kind = 4; goto done;}
case 8:
{t.kind = 5; goto done;}
case 9:
{t.kind = 6; goto done;}
case 10:
{t.kind = 7; goto done;}
case 11:
{t.kind = 8; goto done;}
case 12:
{t.kind = 9; goto done;}
case 13:
{t.kind = 10; goto done;}
case 14:
{t.kind = 11; goto done;}
case 15:
{t.kind = 12; goto done;}
}
done:
t.val = buf.ToString();
return t;
}
/* AW 2003-03-07 get the next token, move on and synch peek token with current */
public static Token Scan () {
t = pt = t.next;
return t;
}
/* AW 2003-03-07 get the next token, ignore pragmas */
public static Token Peek () {
do { // skip pragmas while peeking
pt = pt.next;
} while (pt.kind > maxT);
return pt;
}
/* AW 2003-03-11 to make sure peek start at current scan position */
public static void ResetPeek () { pt = t; }
} // end Scanner
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>EBNF-Visualizer - Manual</title>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Pragma" content="no-cache">
<meta content="EBNF, GIF, Visualizer, Grafik, Syntax, Diagramm" name="keywords">
</head>
<body>
<h1>EBNF Visualizer - Manual</h1>
<h2>Content</h2>
<a href="#Introduction"> Introduction </a><br>
<a href="#Simple"> Simple example </a><br>
<a href="#EBNF"> EBNF - Extended Backus Naur Form</a><br>
<a href="#Writing"> Writing an .ebnf-file </a><br>
<a href="#Menu"> Menu </a><br>
<a href="#Functions"> Functions </a><br>
<a href="#License"> License & Copyright </a><br>
<a href="#Contact"> Contact </a><br>
<h2><a name="Introduction">Introduction</a></h2>
This program visualizes EBNF (Extended Backus Naur Form). Therefore an .ebnf File is required, which contains rules written in EBNF. The program parses the rules, visualizes them in form of syntax diagrams and is able to generate .gif files for further use. Furthermore the program allows to manipulate the look of the generated syntax diagrams.
<h2><a name="Simple">Simple example</a></h2>
<h3>Step 1:</h3>
Create a .ebnf file with a rule just like “A= a [b] c.”. A .ebnf file is just a simple .txt file, just change the ending of the file.
<h3>Step 2:</h3>
Start the program and open the .ebnf file via the menu entry “Load Grammar…”. The program parses it. If there exist errors in the .ebnf file, it would be reported in the log window. Otherwise the rule menu will be activated.<p><img src="Manual\open.JPG" alt="Open a .ebnf file">
<h3>Step 3:</h3>
Choose a rule from the loaded grammar in the rule menu. The chosen rule will be drawn.
<p><img src="Manual\choose.JPG" alt="Chose a rule">
<h3>Step 4 (optional):</h3>
Change the look of the syntax diagram in the menu File/Settings.
<p><img src="Manual\settings.JPG" alt="Settings">
<h3>Step 5 (optional):</h3>
Save the syntax diagram or just copy/paste it.
<h2><a name="EBNF">EBNF - Extended Backus Naur Form</a></h2>
EBNF is used to define the grammar of programming languages.
<br>Therefore a set of rules is specified. These are known as production rules.
They define the patterns or sequences of symbols allowed in the language. Each production rule defines the pattern that represents a named structured part of the language, such as an expression or a statement.
The name of such a part is called a non-terminal symbol in the language. The basic building blocks of the language are symbols which stand for themselves.
These can be individual characters or combinations such as keywords and arithmetic operators. These basic elements of the language are called terminal symbols.
<h2><a name="Writing">Writing an .ebnf-file</a></h2>
The following description is informal but will allow you to write EBNF that works with this program.<p>
A grammar consists of a set of rules. A rule consist of an identifier, followed by “=”, a sequence of meta, terminal and nonterminal symbols and ends with “.” (e.g. “A= a b [c].”)
<h3>Terminal symbol:</h3>
A terminal symbol can be any string. They are separated by space characters. <br>For example in the rule “A = a b [c].” a, b and c are terminal symbols.
<p><img src="Manual\terminal.GIF" alt="Simple example"><p>
It is also possible to put a terminal symbol under quotes (“) or apostrophes (‘) which is required in some cases.
(eg. Quote = "'" a "'".)<p>
<img src="Manual\Quote.GIF" alt="Simple example"><p>It’s also needed for numbers, because identifiers must begin with a character.
<h3>Nonterminal symbol:</h3>
A nonterminal symbol can’t be created in an explicit way.<br>If a terminal symbol matches the string of an rule identifier, it is automatically considered as a nonterminal symbol.<br>
For example, in the rule “A = a A | b.” A is a nonterminal symbol.
<p><img src="Manual\nonterminal.GIF" alt="Simple example">
<h3>Meta symbols:</h3>
<h4>- option “[“ “]”</h4>
The sequence of symbols within these brackets are optional.<br>
(e.g. Rule1 = “begin [optional things] end.”)
<p><img src="Manual\Rule1.GIF" alt="Simple example">
<h4>-iteration “{“ “}”</h4>
The sequence of symbols within these brackets can occur from zero to infinite times.<br>
(e.g. Rule2 = “begin {and again} end.”)
<p><img src="Manual\Rule2.GIF" alt="Simple example">
<h4>-alternative “|”</h4>
It allows to choose a sequence of symbols.<br>
(e.g. Rule3 = “I am a (good | bad) programmer.”)
<p><img src="Manual\Rule3.GIF" alt="Simple example">
<h4>-grouping “(“ “)”</h4>
These brackets are used to group sequences of symbols in a mathematical way.
<h3>Special symbol – Line break:</h3>
This program allows to make explicit line breaks within a syntax diagram. To do this, use “\n” in the outer structure of the rule. That means, it will be ignored within an option, iteration or alternative.<br>
(e.g. “Linebreak = First line \n Second line \n End.”)
<p><img src="Manual\Linebreak.GIF" alt="Simple example">
<h2><a name="Menu">Menu</a></h2>
<p><img src="Manual\open.JPG" alt="Menu">
<h3>File:</h3>
<h4>Load Grammar… :</h4>
Allows to load a grammar file (*.ebnf).
<h4>Save As… :</h4>
The current rule can be stored as .GIF file or as .EMF file.
The Windows Enhanced Metafile Format .EMF is based on vectorgraphics and
therefore better suitable for printing or zooming.
<h4>Copy:</h4>
The current rule is copied to the clipboard as a picture. It is possible to paste it into any program which allows to paste from the clipboard.
<h4>Settings… :</h4>
<p><img src="Manual\settings.JPG" alt="Settings"><br>
In the menu settings the look of the syntax diagrams can be changed.
<h5>Font</h5>
Change the font of terminal and nonterminal symbols.
<h5>Line</h5>
Change the thickness and the color of the line. It is also possible to increase or decrease the size of the arrows.
<h5>Dimensions</h5>
It is possible to increase or decrease the horizontal and vertical gap between the symbols.
The look of the terminal and nonterminal symbols can be changed by increasing or decreasing the gap between the line of the symbol and its name.
<h5>Optimizations</h5>
If the checkbox "Enable optimizations" is activated, the syntaxgraph will be optimized. Any change of this option requires to reload the actual grammar.
<h2><a name="Functions">Functions</a></h2>
<h3>Optimizations:</h3>
This happens implicitly. It is possible to disable them in the settings menu.<br>
If the syntax graph is optimized, redundant und needless productions within a rule are deleted. That means empty nodes, iterations, options and alternatives are removed. If there is an empty alternative, it is moved to the first position. Already existing alternatives are removed.
Furthermore some productions are visualized in a more elegant way,
<br> for example “A = ab {ab}.”
<p><img src="Manual\optimize1not.GIF" alt="Optimize"><img src="Manual\optimize1.GIF" alt="Optimize"><p>
or “B = ab { cd ab}.”
<p><img src="Manual\optimize2not.GIF" alt="Optimize"><img src="Manual\optimize2.GIF" alt="Optimize"><p>
<h3>Navigation:</h3>
It is possible to navigate through an grammar by left-clicking on nonterminal symbols. Right-clicking allows to go back.
<h2><a name="License">License & Copyright</a></h2>
EBNF Visualizer<br>
Copyright (c) 2005 Stefan Schoergenhumer, Markus Dopler<br>
supported by Hanspeter Moessenboeck, University of Linz<br>
<p>
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
<p>
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
<p>
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
<h2><a name="Contact">Contact</a></h2>
For further questions, please write an Email to:<p>
Markus Dopler, k0156207@students.jku.at or<br>
Stefan Schörgenhumer, k0155531@students.jku.at
</body>
</html>
......@@ -567,10 +567,18 @@ cArea.prototype.tocBool = function () {
return this.getValue()[0].tocBool();
};
cArea.prototype.toString = function () {
var _c;
if( this.getRange() ){
return this.getRange().getName();
_c = this.getRange().getName();
}
return this._cells;
else{
_c = this._cells;
}
if( _c.indexOf(":") < 0 ){
_c = _c + ":" + _c;
}
return _c;
};
cArea.prototype.setRange = function ( cell ) {
this._cells = this.value = cell;
......@@ -712,8 +720,6 @@ cArea.prototype.index = function ( r, c, n ) {
return new cError( cErrorType.bad_reference );
}
};
/** @constructor */
......@@ -4585,7 +4591,7 @@ function gaussinv( x ) {
return z;
}
function lcl_getLanczosSum( fZ ) {
function getLanczosSum( fZ ) {
var num = [
23531376880.41075968857200767445163675473,
42919803642.64909876895789904700198885093,
......@@ -4645,8 +4651,8 @@ function lcl_getLanczosSum( fZ ) {
}
/** You must ensure fZ>0; fZ>171.624376956302 will overflow. */
function lcl_GetGammaHelper( fZ ) {
var gamma = lcl_getLanczosSum( fZ ),
function getGammaHelper( fZ ) {
var gamma = getLanczosSum( fZ ),
fg = 6.024680040776729583740234375,
zgHelp = fZ + fg - 0.5;
// avoid intermediate overflow
......@@ -4660,17 +4666,17 @@ function lcl_GetGammaHelper( fZ ) {
}
/** You must ensure fZ>0 */
function lcl_GetLogGammaHelper( fZ ) {
function getLogGammaHelper( fZ ) {
var _fg = 6.024680040776729583740234375, zgHelp = fZ + _fg - 0.5;
return Math.log( lcl_getLanczosSum( fZ ) ) + (fZ - 0.5) * Math.log( zgHelp ) - zgHelp;
return Math.log( getLanczosSum( fZ ) ) + (fZ - 0.5) * Math.log( zgHelp ) - zgHelp;
}
function getLogGamma( fZ ) {
if ( fZ >= maxGammaArgument )
return lcl_GetLogGammaHelper( fZ );
return getLogGammaHelper( fZ );
if ( fZ >= 0 )
return Math.log( lcl_GetGammaHelper( fZ ) );
return Math.log( getGammaHelper( fZ ) );
if ( fZ >= 0.5 )
return Math.log( lcl_GetGammaHelper( fZ + 1 ) / fZ );
return lcl_GetLogGammaHelper( fZ + 2 ) - Math.log( fZ + 1 ) - Math.log( fZ );
return Math.log( getGammaHelper( fZ + 1 ) / fZ );
return getLogGammaHelper( fZ + 2 ) - Math.log( fZ + 1 ) - Math.log( fZ );
}
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment