ã³ã³ãã€ã©ãŒå šäœãèšè¿°ããããã»ã¹å šäœã次ã®å³ã«ç€ºããŸãã MiniJavaããã°ã©ãã³ã°èšèªã®ãœãŒã¹ã³ãŒããå«ããã¡ã€ã«ãå ¥åã«éãããŸãã åºåã¯ãCLRã«ãã£ãŠå®è¡ãããPEãã¡ã€ã«ã§ãã
次ã«ã説æã®å®éçãªéšåã«éäžããããšæããŸãã
MiniJavaããã°ã©ãã³ã°èšèª
MiniJavaã¯ãJavaããã°ã©ãã³ã°èšèªã®ãµãã»ããã§ãã ãªãŒããŒããŒãã¯èš±å¯ãããŠããŸãã;ã³ã³ãœãŒã«ãžã®å°å·ã¯ã
System.out.println(...)
ã¡ãœãããåŒã³åºãããšã«ãã£ãŠæŽæ°ã«ãã£ãŠã®ã¿å®è¡ãããŸãã
e.length
åŒã¯ã
int[]
é åã«ã®ã¿é©çšãããŸãã
Beckus-Naur圢åŒã®ææ³ã®èª¬æïŒèšèªãããžã§ã¯ãã®ãµã€ãhttp://www.cambridge.org/us/features/052182060X/ããååŸïŒïŒ
Goal ::= MainClass ( ClassDeclaration )* <EOF> MainClass ::= "class" Identifier "{" "public" "static" "void" "main" "(" "String" "[" "]" Identifier ")" "{" Statement "}" "}" ClassDeclaration ::= "class" Identifier ( "extends" Identifier )? "{" ( VarDeclaration )* ( MethodDeclaration )* "}" VarDeclaration ::= Type Identifier ";" MethodDeclaration ::= "public" Type Identifier "(" ( Type Identifier ( "," Type Identifier )* )? ")" "{" ( VarDeclaration )* ( Statement )* "return" Expression ";" "}" Type ::= "int" "[" "]" | "boolean" | "int" | Identifier Statement ::= "{" ( Statement )* "}" | "if" "(" Expression ")" Statement "else" Statement | "while" "(" Expression ")" Statement | "System.out.println" "(" Expression ")" ";" | Identifier "=" Expression ";" | Identifier "[" Expression "]" "=" Expression ";" Expression ::= Expression ( "&&" | "<" | "+" | "-" | "*" ) Expression | Expression "[" Expression "]" | Expression "." "length" | Expression "." Identifier "(" ( Expression ( "," Expression )* )? ")" | <INTEGER_LITERAL> | "true" | "false" | Identifier | "this" | "new" "int" "[" Expression "]" | "new" Identifier "(" ")" | "!" Expression | "(" Expression ")" Identifier ::= <IDENTIFIER>
ããã§ãææ³ã¯ãéçµç«¯èšå·ãèšèªãã§ãŒã³ã«åºåããããã®èŠåã«ãã£ãŠè¡šãããŸãã
ã¿ãŒããã«ã¯ãææ³ã®æåŸã®ã·ã³ãã«ã§ãã éçµç«¯èšå·ã¯ããããçµç«¯èšå·ããã³/ãŸãã¯éçµç«¯èšå·ã®çµã¿åããã®ãã§ãŒã³ã«å€æããæšè«èŠåãååšããææ³èšå·ã§ãã αâβãããã§ãαâVãβâïŒNâªVïŒ*ã Nã¯ç«¯æ«ã®ã¢ã«ãã¡ããããVã¯é端æ«ã®ã¢ã«ãã¡ãããã§ãã
ææ³èšè¿°ã®ãã¹ãŠã®ç«¯æ«ã¯ãäºéåŒçšç¬Šã§å²ãŸããäžé£ã®æåãéäžé£ã®æåã§å²ãŸããæåãããã³è§åºŠåŒçšã§ç€ºãããŸãã ææ³å ¬ç-
Goal
ã
MiniJavaãããžã§ã¯ãã®Webãµã€ãããååŸããéä¹ãèšç®ããfactorial.javaããã°ã©ã ã®äŸã䜿çšããŠãã³ã³ãã€ã©ãèšè¿°ããããã»ã¹ïŒILã³ãŒãã®çæãŸã§ïŒãæ€èšããŸãã
class Factorial{ public static void main(String[] a){ System.out.println(new Fac().ComputeFac(10)); } } class Fac { public int ComputeFac(int num){ int num_aux ; if (num < 1) num_aux = 1 ; else num_aux = num * (this.ComputeFac(num-1)) ; return num_aux ; } }
åå¥è§£æ
ãããã¯ã³ã³ãã€ã©ãžã§ãã¬ãŒã¿ã䜿çšããŠå®è¡ããããããã³ã³ãã€ã©ãèšè¿°ããããã2ã€ã®ãã§ãŒãºãçµã¿åãããŸããã çŸåšã ANTLR ã GPPG ã Coco / R ã GOLD Parsing Systemãªã©ãååãªæ°ã®ã³ã³ãã€ã©ãžã§ãã¬ãŒã¿ããããŸãã
ANTLRã䜿çšããã®ã¯ãææ³ãæžãã®ã«äŸ¿å©ã§ãããã¹ããšãã£ã¿ãŒãåããã°ã©ãã£ã«ã«ã·ã§ã«ãåããæœè±¡æ§æããªãŒïŒANTLRWorks 1.4.3ç°å¢ãããŒãžã§ã³2.0ãhttp://tunnelvisionlabs.com/products/demoã«æ¢ã«è¡šç€ºãããŠããããïŒ / antlrworks ïŒã
ã³ã³ãã€ã©ãžã§ãã¬ãŒã¿ãŒã䜿çšãããšãããŒã¯ã³ã®ã»ãããšãææ³ã«å¯Ÿå¿ããæœè±¡æ§æããªãŒïŒASTïŒãååŸã§ããŸãã
Beckus-Naur圢åŒã®ææ³ã®èª¬æãããANTLRãåŠçããããã®ææ³ãã¡ã€ã«ãã³ã³ãã€ã«ããŸããã ææ³ãLLãã¥ãŒã«æžãããå·ŠåŽã®ååž°ãåé€ãã察å¿ããéšåã®CïŒã§ææ³ã·ã³ãã«ã®äœæãèšè¿°ããåŸãããã«ã³ãŒãçæããã»ã¹çšã®ãã¡ã€ã«ãæºåããŸããïŒMiniJava.gææ³ãã¡ã€ã«ã¯ãããžã§ã¯ããã£ã¬ã¯ããªã«ãããŸãããªã³ã¯ã¯ä»¥äžã«ãããŸãïŒã
ãããã£ãŠãããšãã°ãã¡ã€ã³ã¯ã©ã¹ã®äœæã¯æ¬¡ã®ããã«èšè¿°ãããŸãã
mainClassDecl returns [NonTerm value] : CLASS^ id=ID LCURLY! PUBLIC! STATIC! VOID! MAIN! LPAREN! STRING! LBRACK! RBRACK! ID RPAREN! LCURLY! statement=stmtList RCURLY! RCURLY! { $value = NonTerm.CreateMainClassDecl(new Token(TokenType.ID, id.Text, id), statement.valueList); if (flagDebug) Console.WriteLine("mainClassDecl"); } ;
ããã§ãmainClassDeclã¯ã¡ã€ã³ã¯ã©ã¹ã®èª¬æã«å¯Ÿå¿ããã«ãŒã«ã§ã次ã®èª¬æãæ åœããŸãã
MainClass ::= "class" Identifier "{" "public" "static" "void" "main" "(" "String" "[" "]" Identifier ")" "{" Statement "}" "}"
ã^ãèšå·ã¯
CLASS
ããŒã¯ã³ãã«ãŒã«ã®ã«ãŒãã«ãããïŒãèšå·ã¯ ä»ã®ããŒã¯ã³ã®åŸãæ€èšŒãç¡èŠããããã«ANTLRã«æ瀺ããŸãïŒã€ãŸããASTã®æ§ç¯äžã«é€å€ãããŸãïŒã çµæãä¿åããå¿ èŠã®ããã«ãŒã«ïŒã¡ã€ã³ã¯ã©ã¹
ID
ãšãªã¹ã
stmtList
ïŒãå€æ°ïŒãããã
id
ãš
statement
ïŒã«å²ãåœãŠãå¿ èŠããããŸãã ããŒã¯ã³ã¯å€§æåã§èšè¿°ãããã«ãŒã«ã¯å°æåã§èšè¿°ãããããšã«æ³šæããŠãã ããã
$value
ã¯ãã«ãŒãã«ãŒã«ã«æ»ãå€ã§ãã æ»ãå€ã®ã¿ã€ãã¯ã
returns
ããŒã¯ãŒãïŒãã®å Žåã¯
NonTerm
ïŒã®åŸã®è§æ¬åŒ§ã§æ±ºå®ãã
returns
ã
åºåãã¡ã€ã«ã¯ã.NETã®ANTLRã³ã³ãã€ã©ã³ãã³ãã䜿çšããŠçæãããŸãïŒantlr-dotnet-tool-3.3.1.7705ã䜿çšãããŸããïŒã
Antlr3.exe -o "___" "_____\MiniJava.g"
ææ³ã«å ããããç¬èªã®å€æŽïŒäŸ¿å®äžïŒïŒ
-
double
ã¿ã€ããè¿œå ã -
printf(âŠ)
ã³ã³ãœãŒã«ãžã®å°å·ã¯ãSystem.out.println(âŠ)
åŒã³åºãã«äŒŒãŠããŸãã - åå°å·ã®åŸã«ã
Console.Readkey()
ã¡ãœãããåŒã³åºãããŸãïŒãããã°ãç°¡çŽ åããããïŒã
åå¥è§£æãšè§£æã®çµæã¯ãxmlãã¡ã€ã«ãšããŠè¡šç€ºãããŸãã
次ã®
Lexer
ã¯ã©ã¹ã¡ãœããã¯ãåå¥è§£æã®çµæã衚瀺ããããã«äœ¿çšãããŸãã
public void SaveToFile(string fileName) { List<IToken> tokens = TokenStream.GetTokens(); XElement xElement = new XElement("Lexer", from token in tokens select new XElement("Token", new XAttribute("Text", token.Text.TokenToString()), new XAttribute("TokenIndex", token.TokenIndex), new XAttribute("Type", token.Type), new XAttribute("Line", token.Line), new XAttribute("CharPositionInLine", token.CharPositionInLine), new XAttribute("StartIndex", token.StartIndex), new XAttribute("StopIndex", token.StopIndex) ) ); xElement.Save(fileName); }
åå¥è§£æã®çµæã¯152åã®ããŒã¯ã³ã§ãïŒæåã®30åã¯ããã«ãããŸãïŒïŒ
ããŒã¯ã³ãããŒ
<?xml version="1.0" encoding="utf-8"?> <Lexer> <Token Text="class" TokenIndex="0" Type="8" Line="1" CharPositionInLine="0" StartIndex="0" StopIndex="4" /> <Token Text=" " TokenIndex="1" Type="74" Line="1" CharPositionInLine="5" StartIndex="5" StopIndex="5" /> <Token Text="Factorial" TokenIndex="2" Type="26" Line="1" CharPositionInLine="6" StartIndex="6" StopIndex="14" /> <Token Text="{" TokenIndex="3" Type="32" Line="1" CharPositionInLine="15" StartIndex="15" StopIndex="15" /> <Token Text="\n" TokenIndex="4" Type="74" Line="1" CharPositionInLine="16" StartIndex="16" StopIndex="16" /> <Token Text=" " TokenIndex="5" Type="74" Line="2" CharPositionInLine="0" StartIndex="17" StopIndex="17" /> <Token Text=" " TokenIndex="6" Type="74" Line="2" CharPositionInLine="1" StartIndex="18" StopIndex="18" /> <Token Text=" " TokenIndex="7" Type="74" Line="2" CharPositionInLine="2" StartIndex="19" StopIndex="19" /> <Token Text=" " TokenIndex="8" Type="74" Line="2" CharPositionInLine="3" StartIndex="20" StopIndex="20" /> <Token Text="public" TokenIndex="9" Type="56" Line="2" CharPositionInLine="4" StartIndex="21" StopIndex="26" /> <Token Text=" " TokenIndex="10" Type="74" Line="2" CharPositionInLine="10" StartIndex="27" StopIndex="27" /> <Token Text="static" TokenIndex="11" Type="64" Line="2" CharPositionInLine="11" StartIndex="28" StopIndex="33" /> <Token Text=" " TokenIndex="12" Type="74" Line="2" CharPositionInLine="17" StartIndex="34" StopIndex="34" /> <Token Text="void" TokenIndex="13" Type="72" Line="2" CharPositionInLine="18" StartIndex="35" StopIndex="38" /> <Token Text=" " TokenIndex="14" Type="74" Line="2" CharPositionInLine="22" StartIndex="39" StopIndex="39" /> <Token Text="main" TokenIndex="15" Type="41" Line="2" CharPositionInLine="23" StartIndex="40" StopIndex="43" /> <Token Text="(" TokenIndex="16" Type="40" Line="2" CharPositionInLine="27" StartIndex="44" StopIndex="44" /> <Token Text="String" TokenIndex="17" Type="66" Line="2" CharPositionInLine="28" StartIndex="45" StopIndex="50" /> <Token Text="[" TokenIndex="18" Type="31" Line="2" CharPositionInLine="34" StartIndex="51" StopIndex="51" /> <Token Text="]" TokenIndex="19" Type="57" Line="2" CharPositionInLine="35" StartIndex="52" StopIndex="52" /> <Token Text=" " TokenIndex="20" Type="74" Line="2" CharPositionInLine="36" StartIndex="53" StopIndex="53" /> <Token Text="a" TokenIndex="21" Type="26" Line="2" CharPositionInLine="37" StartIndex="54" StopIndex="54" /> <Token Text=")" TokenIndex="22" Type="60" Line="2" CharPositionInLine="38" StartIndex="55" StopIndex="55" /> <Token Text="{" TokenIndex="23" Type="32" Line="2" CharPositionInLine="39" StartIndex="56" StopIndex="56" /> <Token Text="\n" TokenIndex="24" Type="74" Line="2" CharPositionInLine="40" StartIndex="57" StopIndex="57" /> <Token Text="\t" TokenIndex="25" Type="74" Line="3" CharPositionInLine="0" StartIndex="58" StopIndex="58" /> <Token Text="System.out.println" TokenIndex="26" Type="54" Line="3" CharPositionInLine="1" StartIndex="59" StopIndex="76" /> <Token Text="(" TokenIndex="27" Type="40" Line="3" CharPositionInLine="19" StartIndex="77" StopIndex="77" /> <Token Text="new" TokenIndex="28" Type="50" Line="3" CharPositionInLine="20" StartIndex="78" StopIndex="80" /> <Token Text=" " TokenIndex="29" Type="74" Line="3" CharPositionInLine="23" StartIndex="81" StopIndex="81" /> ... </Lexer>
ASTã®å Žåãææ³ã®åèŠçŽ ãè¡šããªããžã§ã¯ãã¢ãã«ãã³ã³ãã€ã«ããŸããã ã¯ã©ã¹ã¯ãé端æ«ãšç«¯æ«ã«å¯Ÿå¿ããŸãã ã¯ã©ã¹å³ã次ã®å³ã«ç€ºããŸãã
åºæ¬ã¯ã©ã¹
BaseSymbol
ã¯ãçµåãããã¢ã«ãã¡ãããããã®ææ³èšå·ã§ããã
NonTerm
ããŒã¯ã³ïŒç«¯æ«ïŒããã³
NonTerm
端æ«ã¯ããããç¶æ¿ãããŸãã
MainClassDecl
ææ³å ¬çã
MainClassDecl
ã¡ã€ã³ã¯ã©ã¹ã
ClassDecl
ã¯ã©ã¹ã
MethodDecl
ã¡ãœããã
ExtendsClause
ã¯ã©ã¹ã®ç¶æ¿ã
TypeDecl
ã¿ã€ãã
VarDecl
å€æ°ã
ExpressionDecl
åŒã
StatementDecl
æŒç®åã®åºæ¬ã¯ã©ã¹ã æŒç®åã¯ã©ã¹ïŒ
IfStatement
ã¯æ¡ä»¶ã¹ããŒãã¡ã³ãã
WhileStatement
ã¯
while
ã¹ããŒãã¡ã³ãã
StatementList
ã¯
StatementList
ã®ãªã¹ãã
AssignVarStatement
ã¯å®£èšãšæ°ããå€æ°ã®å²ãåœãŠã
AssignIdStatement
ã¯ä»¥åã«å®£èšãããèå¥åã«ããå€æ°å²ãåœãŠã§ãã
ãããã®ã¯ã©ã¹ã¯ãASTLRãçæããããã«ANTLRææ³ãã¡ã€ã«ã§äœ¿çšãããŸãã
解æã«ãã£ãŠçæãããASTè¡šçŸã¯ã
ToXmlTree()
åºæ¬ã¯ã©ã¹ã®ååž°çãª
ToXmlTree()
ã¡ãœããã䜿çšããŠxmlãã¡ã€ã«ã«ä¿åãããŸãã ã¡ãœããã¯ããŒã¯ã³ã«å¯ŸããŠã®ã¿ãªãŒããŒã©ã€ããããŸãã åºæ¬ã¯ã©ã¹
BaseSymbol
ã¡ãœããã¯æ¬¡ã®ãšããã§ãã
public virtual XElement ToXmlTree() { XElement elements = new XElement(ToString()); Symbols.ForEach(symbol => { if (symbol != null) { XElement el = symbol.ToXmlTree(); elements.Add(el); } }); return elements; }
ããªãŒåœ¢æã®çµæã¯æ¬¡ã®ãšããã§ãã
AST
<?xml version="1.0" encoding="utf-8"?> <Program> <MainClass> <ID Value="Factorial" /> <PrintStatement> <MethodCallExpression> <NewStatement> <ID Value="Fac" /> </NewStatement> <ID Value="ComputeFac" /> <ArgumentListExpression> <INTEGER Value="10" /> </ArgumentListExpression> </MethodCallExpression> </PrintStatement> </MainClass> <Class> <ID Value="Fac" /> <Method> <INT /> <ID Value="ComputeFac" /> <FormalArgumentList> <Variable> <INT /> <ID Value="num" /> </Variable> </FormalArgumentList> <StatementList> <VarStatement> <Variable> <INT /> <ID Value="num_aux" /> </Variable> </VarStatement> <IfElseStatement> <LessExpression> <ID Value="num" /> <INTEGER Value="1" /> </LessExpression> <IdStatement> <ID Value="num_aux" /> <INTEGER Value="1" /> </IdStatement> <IdStatement> <ID Value="num_aux" /> <MultiplyExpression> <ID Value="num" /> <MethodThisCallExpression> <ID Value="ComputeFac" /> <ArgumentListExpression> <MinusExpression> <ID Value="num" /> <INTEGER Value="1" /> </MinusExpression> </ArgumentListExpression> </MethodThisCallExpression> </MultiplyExpression> </IdStatement> </IfElseStatement> </StatementList> <ID Value="num_aux" /> </Method> </Class> </Program>
äŸå€ããã£ããããããã«ã
ParserException
ãšã
CompilerException
ã³ã³ãã€ã©äŸå€ã®åºæ¬ã¯ã©ã¹ããç¶æ¿ããã
CodeGenerationException
ã³ãŒãã®çæã«äœ¿çšãããäŸå€ã¯ã©ã¹ãäœæã
CodeGenerationException
ã
ãããã£ãŠãæ§æ解æã®çµæãšããŠãæœè±¡æ§æããªãŒãã³ã³ãã€ã«ããã次ã®ãã§ãŒãºã§ILã³ãŒããçæãããŸãã
ILã³ãŒãçæ
äžä»£ã®ããã«ãç§ã¯åã³è»èŒªã®åçºæãéå§ããŸããã§ããããCodeproject http://www.codeproject.com/Articles/20921/RunSharp-Reflection-Emit-Has-Never-Been-Easierã«æçš¿ãããæ¢åã®RunSharpãããžã§ã¯ããå©çšããŸããã RunSharpã¯ãSystem.Reflection.Emitåå空éããã®ã¯ã©ã¹ã¡ãœããåŒã³åºããã«ãã»ã«åãããããžã§ã¯ãã§ãILã³ãŒãã®çæããã»ã¹ãç°¡çŽ åããŸãã
ã³ãŒãçæã«ã¯ã次ã®ããŒã¿æ§é ã䜿çšãããŸãïŒããã°ã©ã ã¯ã©ã¹ããŒãã«ïŒã¯ã©ã¹ã®ã³ãŒãçæããã³ããã¯ã©ã¹ã®ã¡ãœãããå¥ã®ã¯ã©ã¹ãåç §ããå Žåãããã³ãã®éã®å ŽåïŒãåã¯ã©ã¹ã®ã¡ãœããã®ãªã¹ãïŒã¡ãœããã®ã³ãŒãçæã®å ŽåïŒãããŒã«ã«å€æ°ã®ãªã¹ãïŒè¿œè·¡ãªã³ã¯ã®å ŽåïŒ
if
ã
while
ãããã¯ããã³ã¡ãœããã®æ¬äœå ã®ããŒã«ã«å€æ°ãããŒã«ã«å€æ°ã®ã¹ã¿ãã¯ïŒåé ããã³ãã€ããªæŒç®ãå®è¡ããããïŒãçŸåšã®ã¡ãœããã®ä»®ãã©ã¡ãŒã¿ã®ãªã¹ãã
ã³ãŒãçæå¶åŸ¡ããŒãã«ã䜿çšãããŸããããã«ã¯ãææ³ã·ã³ãã«ã®ååãšãã³ãŒãã衚瀺ããããšãã«ã³ãŒããçæããã¡ãœãããå«ãŸããŸãã
ILã³ãŒãã®çæã¯ã
Generate(BaseSymbol root)
ã®ã¡ã€ã³ã®ååž°ã¡ãœãã
Generate(BaseSymbol root)
ãŸãã
private void Generate(BaseSymbol root) { if (root == null) { return; } if (root.GrammarMember == GrammarMemberType.NonTerm) { NonTerm nonTerm = root as NonTerm; _compilerLogger.PrintGenerateNonTerm(nonTerm); if (_emitTableDictionary.ContainsKey(nonTerm.TypeNonTerm)) { _emitTableDictionary[nonTerm.TypeNonTerm](nonTerm); } else { root.Symbols.ForEach(Generate); } } }
ãã®ã¡ãœãã
root
éçµç«¯ã§ãããã©ãããå€æã
root
éçµç«¯ã®ã¿ã€ããã³ã³ãããŒã«ããŒãã«ã«å«ãŸããŠããå Žåãã³ã³ãããŒã«ããŒãã«ãçæããã¡ãœãããå®è¡ãããŸããããã§ãªãå Žåã
root
å«ãŸããåææ³æåã«å¯ŸããŠååž°çã«çæãå®è¡ãããŸã
ã³ã³ãããŒã«ããŒãã«ã«ã¯ã次ã®ææ³æåã®æ瀺ãçæãã次ã®ã¡ãœãããå«ãŸããŠããŸãã
- EmitMainClass-ããã°ã©ã ã®ã¡ã€ã³ã¯ã©ã¹ã
- EmitClass-ããã°ã©ã ã®ã¯ã©ã¹ïŒã¡ã€ã³ã¯ã©ã¹ãé€ãïŒ;
- EmitClassVar-ã¯ã©ã¹å€æ°ïŒãã©ã€ããŒãã¯ã©ã¹ãã£ãŒã«ãïŒ;
- EmitMethod-ã¯ã©ã¹ã¡ãœããã
- EmitVarStatement-æ°ããåŒå€æ°ã®å³åŽãžã®å²ãåœãŠã
- EmitNewStatement-å€æ°ã®ã¡ã¢ãªå²ãåœãŠã
- EmitNewArrayStatement-é åãžã®ã¡ã¢ãªã®å²ãåœãŠã
- EmitIdStatement-å³åŽã®åŒãžã®å€æ°ã®å²ãåœãŠã
- EmitArrayIdStatement-å³åŽã®åŒã®é åãžã®å²ãåœãŠã
- EmitArrayIndiââciesStatement-é åã€ã³ããã¯ã¹ã«ããã¢ã¯ã»ã¹ã
- EmitMethodCallExpression-ã¡ãœããåŒã³åºãã
- EmitBinaryExpression-ãã€ããªæŒç®ã
- EmitUnaryExpression-åé æŒç®ã
- EmitPrintStatement-ã¹ããŒãã¡ã³ãã®å°å·ã
- EmitIfStatement-æ¡ä»¶;
- EmitWhileStatement-whileã«ãŒãã
- EmitLengthFunctionExpression-é åã®é·ãã
ãããã®ã¡ãœããã®äžéšã¯ãååž°ã¡ãœãã
Generate()
åŒã³åºããŸãã
ãããã£ãŠãã¡ãœããåœä»€ãçæããã¡ãœããã¯æ¬¡ã®ãšããã§ãã
private void EmitMethod(NonTerm nonTerm) { Token typeMethodDeclSimple; Token methodName; List<BaseSymbol> formalParametersList; BaseSymbol methodStatementList; BaseSymbol returnStatement; NonTermFactory.GetMethodDecl(nonTerm, out typeMethodDeclSimple, out methodName, out formalParametersList, out methodStatementList, out returnStatement); _currentFormalArgumentList.Clear(); foreach (BaseSymbol symbol in formalParametersList) { Token type; Token id; NonTermFactory.GetFormalArgumentDeclaration(symbol, out type, out id); _currentFormalArgumentList.Add(id.Value); } _compilerLogger.PrintRefreshFormalArgumentList(_currentFormalArgumentList); _currentMethod = _methodsTables[_currentClass.Name][methodName.Value]; _g = _currentMethod; GeneratePreInitLocalVariables(methodStatementList); Generate(methodStatementList); Type resultType = GetVariableType(typeMethodDeclSimple); string nameResult = AddTempLocalVariable(resultType); EmitExpression(returnStatement, resultType, nameResult); try { _g.Return(_currentOperandTempResult); } catch (InvalidCastException ex) { throw new CodeGenerationException(MessagesHelper.TypeMismatchEx, returnStatement.ToStringInfo(), ex); } ClearCurrentBlockLocalVariables(); }
ãŸããã¡ãœããã«å¿ èŠãªãã¹ãŠã®ããŒã¿ãååŸããŸãïŒæ»ãå€ã®åã¯
typeMethodDeclSimple
ãã¡ãœããã®ååã¯
methodName
ãä»®ãã©ã¡ãŒã¿ãŒã®ãªã¹ãã
methodStatementList
ãã¡ãœããã®æŒç®åã®ãªã¹ã
methodStatementList
ããã³æ»ãåŒ
returnStatement
ïŒã 次ã«ãçŸåšã®åœ¢åŒå€æ°ã®ãªã¹ãã«å ¥åããŸãããã®åŸãå€æ°
_currentMethod
ïŒRunSharpã©ã€ãã©ãªã®
MethodGen
ãªã©ïŒ
_currentMethod
å²ãåœãŠãããã¡ãœãããçæãããŸãã 次ã«ã
GeneratePreInitLocalVariables()
ã¡ãœããã§ãããŒã«ã«å€æ°ã®ãªã¹ããçæãããã¡ãœããã®å 容ãååž°çã«çæããã
return
ããŒã¯ãŒãã®åŸã«ââæ¥ãã¡ãœããã®çµæãè¿ãæŒç®åãçæãããæåŸã«ãããã¯ã®ããŒã«ã«å€æ°ã®ãªã¹ããã¯ãªã¢ãããŸãã
ãŸããå€æ°ã®å²ãåœãŠæäœãçæããã¡ãœããã¯æ¬¡ã®ãšããã§ãã
private void EmitIdStatement(NonTerm nonTerm) { Token idToken; BaseSymbol expression; NonTermFactory.GetAssignIdStatement(nonTerm, out idToken, out expression); Operand operand; if (_currentFormalArgumentList.Contains(idToken.Value)) { operand = _g.Arg(idToken.Value); } else if (_localVariablesTable.ContainsKey(idToken.Value)) { operand = _localVariablesTable[idToken.Value]; } else { operand = _g.This().Field(idToken.Value); } _currentOperandTempResult = EmitExpression(expression, operand.Type, idToken.Value); try { _g.Assign(operand, _currentOperandTempResult); } catch (InvalidCastException ex) { throw new CodeGenerationException(MessagesHelper.AssignTypeMismatchEx, expression.ToStringInfo(), ex); } }
ããã§ã¯ãæåã«ããŒã¯ã³ãååŸããŸããããŒã¯ã³ã«ã¯ãå³åŽã®åŒïŒ
idToken
ïŒãšåŒèªäœïŒ
expression
ïŒãå²ãåœãŠãŸãã 次ã«ãå€æ°ãã©ãããæ¥ãããå€æããŸãïŒä»®ãã©ã¡ãŒã¿ãŒã®ãªã¹ãïŒ
_currentFormalArgumentList
ïŒãããŒã«ã«å€æ°ã®ããŒãã«ïŒ
_localVariablesTable
ïŒããŸãã¯ã¯ã©ã¹å€æ°ãã©ãããå€æããŸãã ãã®åŸã
EmitExpression()
ã¡ãœãããåŒã³åºããŠå³åŽã®åŒãèšç®ããå²ãåœãŠãçæããŸãã
åæ§ã«ãä»ã®ãã¶ã€ã³ã®è©³çŽ°ãèæ ®ããŠããããã®ã³ãŒããçæãããŸãã
éä¹èšç®ããã°ã©ã ã®ã³ãŒãçæã®çµæã®ãã°ã¯æ¬¡ã®ãšããã§ãã
ã³ãŒãçæãã°
ã¯ã©ã¹ããã³ã¡ãœããã·ã°ããã£ã®çæ ã¯ã©ã¹fac ComputeFac System.Int32ã¡ãœãã ããã°ã©ã ã®æ瀺ã®çæ MainClassã®æ瀺ã®çæ ãã®ãããã¯ã«ããŒã«ã«å€æ°ãèŠã€ãããŸãã PrintStatementã®æ瀺ã®çæ MethodCallExpressionã®åœä»€ã®çæ NewStatementã®æ瀺ã®çæ ã¯ã©ã¹ã®æ瀺ã®çæ ã¡ãœããã®æ瀺ã®çæ çŸåšã®ã¡ãœãããã©ã¡ãŒã¿ã®ãªã¹ããæŽæ° num ãããã¯ã®å€æ°ãè¿œå ããŸãã num_aux StatementListã®æ瀺ã®çæ VarStatementã®æ瀺ãçæãã IfElseStatementã®æ瀺ã®çæ LessExpressionã®åœä»€ã®çæ ãã®ãããã¯ã«ããŒã«ã«å€æ°ãèŠã€ãããŸãã IdStatementã®æ瀺ã®çæ ãã®ãããã¯ã«ããŒã«ã«å€æ°ãèŠã€ãããŸãã IdStatementã®æ瀺ã®çæ MultiplyExpressionã®åœä»€ã®çæ MethodThisCallExpressionã®åœä»€ã®çæ MinusExpressionã®æ瀺ã®çæ åé€ãããå€æ° num_aux
ã³ã³ãœãŒã«ã¢ããªã±ãŒã·ã§ã³ã¯ã次ã®ã³ãã³ãã©ã€ã³åŒæ°ãåãã³ã³ãã€ã©ãŒçšã«äœæãããŠããŸãã
-i < > [-o < >]
åºåãã£ã¬ã¯ããªãæå®ãããŠããªãå Žåãåºåãã¡ã€ã«ã¯ã¢ããªã±ãŒã·ã§ã³ãèµ·åããããã£ã¬ã¯ããªã«äœæãããŸãã ãµã³ãã«ãšã¢ããªã±ãŒã·ã§ã³èªäœã¯ãSamplesãã£ã¬ã¯ããªã«ãããŸãã
ãããã«
å šäœãšããŠãæ¢åã®éçºããŒã«ã䜿çšããŠãCïŒã§.NET Frameworkçšã®MiniJavaããã°ã©ãã³ã°èšèªã³ã³ãã€ã©ãäœæããæ¹æ³ã«ã€ããŠèª¬æããŸããã ããã§ã¯ãã³ã³ãã€ã©ã®äœæã«å¿ èŠãªäžäœã¬ãã«ã®ãã€ã³ãã«çŠç¹ãåœãŠãŸããã
æžãããã³ã³ãã€ã©ã¯ãéä¹èšç®ããã€ããªæ€çŽ¢ãããã«ãœãŒããããªãŒãã©ããŒãµã«ãã¯ã€ãã¯ãœãŒããç·åœ¢æ€çŽ¢ããªã³ã¯ãªã¹ãã®äœæããã€ããªããªãŒã®äœæãªã©ãMiniJavaãããžã§ã¯ãããŒã ããŒãžããã®äŸãæ£åžžã«åŠçããŸãã
ãããžã§ã¯ãã®ãœãŒã¹ã³ãŒãã¯GitHubã§å ¥æã§ããŸã ã
ãœãŒã¹
äžè¬ïŒçè«ãšå®è·µïŒ
- ã¢ãããããã¯ãŒã¯ã¹ããŠã«ãã³ã ã³ã³ãã€ã©ãŒ ååãæè¡ãããŒã«ã
- ãããœãããã«ãã§ãã é¢æ£æ°åŠã
- .NET Frameworkçšã®èšèªã³ã³ãã€ã©ãŒã®äœæhttp://msdn.microsoft.com/en-us/magazine/cc136756.aspx
ANTLR
- ANTLRãã¥ãŒããªã¢ã«-åŒèšèªhttp://meri-stuff.blogspot.ru/2011/09/antlr-tutorial-expression-language.html
- ANTLRã䜿çšããããŒãµãŒã®äœæhttp://club.shelek.ru/viewart.php?id=39
- ANTLRã«é¢ããåªããå ¥éãã¬ãŒã³ããŒã·ã§ã³http://fmt.cs.utwente.nl/courses/vertalerbouw/sheets/vb-04-antlr-1-4up.pdf
Minijava
- MiniJavaã®æŠèŠhttp://www-cs-faculty.stanford.edu/~eroberts//papers/SIGCSE-2001/MiniJava.pdf
- MiniJavaã¿ã€ãã·ã¹ãã http://www.cs.ucla.edu/~palsberg/course/cs132/miniJava-typesystem.pdf
- MiniJavaæ§æhttp://www.cs.purdue.edu/homes/hosking/502/project/grammar.html