Compare commits
13 Commits
93702071fb
...
7cbf8aad08
Author | SHA1 | Date | |
---|---|---|---|
|
7cbf8aad08 | ||
af7162ea54 | |||
fa9cb761d5 | |||
fa2dc24aa0 | |||
fe4091da99 | |||
db2b4a142c | |||
95063ac64f | |||
4108eb58c1 | |||
ecd778cc70 | |||
e5baa701b2 | |||
5d49da69a6 | |||
b8e566a2a0 | |||
6d39110794 |
@ -4,14 +4,46 @@ import Test.HUnit
|
||||
import Parser.Lexer
|
||||
|
||||
|
||||
testCommentSomething = TestCase $ assertEqual "scan /*Something*/" [Comment "/*Something*/"] $ alexScanTokens "/*Something*/"
|
||||
testEmptyComment = TestCase $ assertEqual "scan /*x*/" [Comment "/**/"] $ alexScanTokens "/**/"
|
||||
testLineComment = TestCase $ assertEqual "scan // comment" [Comment "// comment"] $ alexScanTokens "// comment"
|
||||
emptyTokenList :: [Token]
|
||||
emptyTokenList = []
|
||||
testCommentSomething = TestCase $ assertEqual "scan '/*Something*/'" emptyTokenList $ alexScanTokens "/*Something*/"
|
||||
testEmptyComment = TestCase $ assertEqual "scan '/*x*/'" emptyTokenList $ alexScanTokens "/**/"
|
||||
testLineComment = TestCase $ assertEqual "scan '// comment'" emptyTokenList $ alexScanTokens "// comment"
|
||||
testLineCommentEnds = TestCase $ assertEqual "scan '// com\\n'" emptyTokenList $ alexScanTokens "// com\n"
|
||||
|
||||
testIdentifier = TestCase $ assertEqual "scan 'identifier'" [IDENTIFIER "identifier"] $ alexScanTokens "identifier"
|
||||
testShortIdentifier = TestCase $ assertEqual "scan 'i'" [IDENTIFIER "i"] $ alexScanTokens "i"
|
||||
testIdentifierWithNumber = TestCase $ assertEqual "scan 'i2'" [IDENTIFIER "i2"] $ alexScanTokens "i2"
|
||||
|
||||
testKeywordBreak = TestCase $ assertEqual "scan 'break'" [BREAK] $ alexScanTokens "break"
|
||||
testKeywordInt = TestCase $ assertEqual "scan 'int'" [INT] $ alexScanTokens "int"
|
||||
|
||||
testIntLiteral = TestCase $ assertEqual "scan '234'" [INTEGERLITERAL 234] $ alexScanTokens "234"
|
||||
testIntLiteral2 = TestCase $ assertEqual "scan '54_2'" [INTEGERLITERAL 542] $ alexScanTokens "54_2"
|
||||
|
||||
testCharLiteral = TestCase $ assertEqual "scan ''f''" [CHARLITERAL 'f'] $ alexScanTokens "'f'"
|
||||
|
||||
testBoolLiteralTrue = TestCase $ assertEqual "scan 'true'" [BOOLLITERAL True] $ alexScanTokens "true"
|
||||
testBoolLiteralFalse = TestCase $ assertEqual "scan 'false'" [BOOLLITERAL False] $ alexScanTokens "false"
|
||||
|
||||
testLBrace = TestCase $ assertEqual "scan '('" [LBRACE] $ alexScanTokens "("
|
||||
testAnd = TestCase $ assertEqual "scan '&&'" [AND] $ alexScanTokens "&&"
|
||||
|
||||
tests = TestList [
|
||||
TestLabel "TestCommentSomething" testCommentSomething,
|
||||
TestLabel "TestEmptyComment" testEmptyComment,
|
||||
TestLabel "TestLineComment" testLineComment
|
||||
TestLabel "TestLineComment" testLineComment,
|
||||
TestLabel "TestLineCommentEnds" testLineCommentEnds,
|
||||
TestLabel "TestIdentifier" testIdentifier,
|
||||
TestLabel "TestShortIdentifier" testShortIdentifier,
|
||||
TestLabel "TestIdentifierWithNumber" testIdentifierWithNumber,
|
||||
TestLabel "TestKeywordBreak" testKeywordBreak,
|
||||
TestLabel "TestKeywordInt" testKeywordInt,
|
||||
TestLabel "TestIntLiteral" testIntLiteral,
|
||||
TestLabel "TestIntLiteral2" testIntLiteral2,
|
||||
TestLabel "TestCharLiteral" testCharLiteral,
|
||||
TestLabel "TestBoolLiteralTrue" testBoolLiteralTrue,
|
||||
TestLabel "TestBoolLiteralFalse" testBoolLiteralFalse,
|
||||
TestLabel "TestLBrace" testLBrace,
|
||||
TestLabel "TestAnd" testAnd
|
||||
]
|
28
Test/TestParser.hs
Normal file
28
Test/TestParser.hs
Normal file
@ -0,0 +1,28 @@
|
||||
module TestParser(tests) where
|
||||
|
||||
import Test.HUnit
|
||||
import Parser.Lexer
|
||||
import Parser.JavaParser
|
||||
import Ast
|
||||
|
||||
|
||||
testSingleEmptyClass = TestCase $
|
||||
assertEqual "expect single empty class hello" [Class "Hello" [] []] $
|
||||
parse [CLASS, IDENTIFIER "Hello", LBRACKET, RBRACKET]
|
||||
testTwoEmptyClasses = TestCase $
|
||||
assertEqual "expect two empty classes" [Class "Class1" [] [], Class "Class2" [] []] $
|
||||
parse [CLASS,IDENTIFIER "Class1",LBRACKET,RBRACKET,CLASS,IDENTIFIER "Class2",LBRACKET,RBRACKET]
|
||||
testBooleanField = TestCase $
|
||||
assertEqual "expect class with boolean field" [Class "WithBool" [] [VariableDeclaration "boolean" "value" Nothing]] $
|
||||
parse [CLASS,IDENTIFIER "WithBool",LBRACKET,BOOLEAN,IDENTIFIER "value",SEMICOLON,RBRACKET]
|
||||
testIntField = TestCase $
|
||||
assertEqual "expect class with int field" [Class "WithInt" [] [VariableDeclaration "int" "value" Nothing]] $
|
||||
parse [CLASS,IDENTIFIER "WithInt",LBRACKET,INT,IDENTIFIER "value",SEMICOLON,RBRACKET]
|
||||
|
||||
|
||||
tests = TestList [
|
||||
testSingleEmptyClass,
|
||||
testTwoEmptyClasses,
|
||||
testBooleanField,
|
||||
testIntField
|
||||
]
|
@ -3,9 +3,12 @@ module Main where
|
||||
import Test.HUnit
|
||||
import TestLexer
|
||||
import TestByteCodeGenerator
|
||||
import TestParser
|
||||
|
||||
otherTest = TestCase $ assertEqual "math" (4+3) 7
|
||||
|
||||
tests = TestList [TestLabel "TestLexer" TestLexer.tests, TestLabel "mathTest" otherTest, TestLabel "bytecodeTest" TestByteCodeGenerator.tests]
|
||||
tests = TestList [
|
||||
TestLabel "TestLexer" TestLexer.tests,
|
||||
TestLabel "TestParser" TestParser.tests,
|
||||
TestLabel "TestByteCodeGenerator" TestByteCodeGenerator.tests]
|
||||
|
||||
main = do runTestTTAndExit Main.tests
|
@ -1,31 +1,48 @@
|
||||
name: MiniJavaCompiler
|
||||
version: 0.1.0.0
|
||||
build-type: Simple
|
||||
cabal-version: >= 1.10
|
||||
Synopsis: A compiler for a minimal version of Java with watered down syntax.
|
||||
|
||||
executable compiler
|
||||
main-is: Main.hs
|
||||
build-depends: base,
|
||||
array,
|
||||
HUnit,
|
||||
utf8-string,
|
||||
bytestring
|
||||
default-language: Haskell2010
|
||||
hs-source-dirs: src,
|
||||
src/ByteCode,
|
||||
src/ByteCode/ClassFile
|
||||
build-tool-depends: alex:alex, happy:happy
|
||||
other-modules: Ast, Example, Typecheck, ByteCode.ByteUtil, ByteCode.ClassFile, ByteCode.ClassFile.Generator, ByteCode.Constants
|
||||
|
||||
test-suite tests
|
||||
type: exitcode-stdio-1.0
|
||||
main-is: TestSuite.hs
|
||||
hs-source-dirs: src,Test
|
||||
build-depends: base,
|
||||
array,
|
||||
HUnit,
|
||||
utf8-string,
|
||||
bytestring
|
||||
build-tool-depends: alex:alex, happy:happy
|
||||
other-modules: TestLexer, TestByteCodeGenerator
|
||||
name: MiniJavaCompiler
|
||||
version: 0.1.0.0
|
||||
build-type: Simple
|
||||
cabal-version: >= 1.10
|
||||
Synopsis: A compiler for a minimal version of Java with watered down syntax.
|
||||
|
||||
executable compiler
|
||||
main-is: Main.hs
|
||||
build-depends: base,
|
||||
array,
|
||||
HUnit,
|
||||
utf8-string,
|
||||
bytestring
|
||||
default-language: Haskell2010
|
||||
hs-source-dirs: src,
|
||||
src/ByteCode,
|
||||
src/ByteCode/ClassFile
|
||||
build-tool-depends: alex:alex, happy:happy
|
||||
other-modules: Parser.Lexer,
|
||||
Parser.JavaParser
|
||||
Ast,
|
||||
Example,
|
||||
Typecheck,
|
||||
ByteCode.ByteUtil,
|
||||
ByteCode.ClassFile,
|
||||
ByteCode.ClassFile.Generator,
|
||||
ByteCode.Constants
|
||||
|
||||
test-suite tests
|
||||
type: exitcode-stdio-1.0
|
||||
main-is: TestSuite.hs
|
||||
hs-source-dirs: src,Test
|
||||
build-depends: base,
|
||||
array,
|
||||
HUnit,
|
||||
utf8-string,
|
||||
bytestring
|
||||
build-tool-depends: alex:alex, happy:happy
|
||||
other-modules: Parser.Lexer,
|
||||
Parser.JavaParser,
|
||||
Ast,
|
||||
TestLexer,
|
||||
TestParser,
|
||||
TestByteCodeGenerator,
|
||||
ByteCode.ByteUtil,
|
||||
ByteCode.ClassFile,
|
||||
ByteCode.ClassFile.Generator,
|
||||
ByteCode.Constants
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
module Parser.JavaParser (parse) where
|
||||
--import AbsSyn
|
||||
import Ast
|
||||
import Parser.Lexer
|
||||
}
|
||||
|
||||
@ -14,10 +14,10 @@ import Parser.Lexer
|
||||
CASE { CASE }
|
||||
CHAR { CHAR }
|
||||
CLASS { CLASS}
|
||||
IDENTIFIER { IDENTIFIER $$}
|
||||
INTLITERAL { INTLITERAL $$}
|
||||
IDENTIFIER { IDENTIFIER $$ }
|
||||
INTLITERAL { INTEGERLITERAL $$}
|
||||
DOT { DOT }
|
||||
MOD { MOD }
|
||||
MOD { MODULO }
|
||||
TIMESEQUAL { TIMESEQUAL }
|
||||
GREATEREQUAL { GREATEREQUAL }
|
||||
WHILE { WHILE }
|
||||
@ -29,30 +29,29 @@ import Parser.Lexer
|
||||
THIS { THIS }
|
||||
STATIC { STATIC }
|
||||
PROTECTED { PROTECTED }
|
||||
TILDE { TILDE }
|
||||
MUL { MUL }
|
||||
TILDE { BITWISENOT }
|
||||
MUL { TIMES }
|
||||
MINUS { MINUS }
|
||||
EXCLMARK { EXCLMARK }
|
||||
EXCLMARK { NOT }
|
||||
IF { IF }
|
||||
ELSE { ELSE }
|
||||
DIVIDEEQUAL { DIVIDEEQUAL }
|
||||
DIVIDEEQUAL { DIVEQUAL }
|
||||
NEW { NEW }
|
||||
LBRACKET { LBRACKET }
|
||||
JNULL { JNULL }
|
||||
BOOLLITERAL { BOOLLITERAL }
|
||||
JNULL { NULLLITERAL }
|
||||
BOOLLITERAL { BOOLLITERAL $$ }
|
||||
DIV { DIV }
|
||||
LOGICALOR { LOGICALOR }
|
||||
LOGICALOR { OR }
|
||||
NOTEQUAL { NOTEQUAL }
|
||||
INSTANCEOF { INSTANCEOF }
|
||||
ANDEQUAL { ANDEQUAL }
|
||||
ASSIGN { ASSIGN }
|
||||
DECREMENT { DECREMENT }
|
||||
STRINGLITERAL { STRINGLITERAL }
|
||||
CHARLITERAL { CHARLITERAL }
|
||||
CHARLITERAL { CHARLITERAL $$ }
|
||||
AND { AND }
|
||||
XOREQUAL { XOREQUAL }
|
||||
RETURN { RETURN }
|
||||
QUESMARK { QUESMARK }
|
||||
QUESMARK { QUESTIONMARK }
|
||||
SHIFTLEFTEQUAL { SHIFTLEFTEQUAL }
|
||||
RBRACKET { RBRACKET }
|
||||
COMMA { COMMA }
|
||||
@ -68,7 +67,7 @@ import Parser.Lexer
|
||||
INT { INT }
|
||||
ABSTRACT { ABSTRACT }
|
||||
SEMICOLON { SEMICOLON }
|
||||
SIGNEDSHIFTRIGHTEQUAL { SIGNEDSHIFTRIGHTEQUAL }
|
||||
SIGNEDSHIFTRIGHTEQUAL { SHIFTRIGHTEQUAL }
|
||||
UNSIGNEDSHIFTRIGHTEQUAL { UNSIGNEDSHIFTRIGHTEQUAL }
|
||||
PLUSEQUAL { PLUSEQUAL }
|
||||
OREQUAL { OREQUAL }
|
||||
@ -76,138 +75,146 @@ import Parser.Lexer
|
||||
LESS { LESS }
|
||||
%%
|
||||
|
||||
compilationunit : typedeclarations { }
|
||||
compilationunit : typedeclarations { $1 }
|
||||
|
||||
typedeclarations : typedeclaration { }
|
||||
| typedeclarations typedeclaration { }
|
||||
typedeclarations : typedeclaration { [$1] }
|
||||
| typedeclarations typedeclaration { $1 ++ [$2] }
|
||||
|
||||
name : qualifiedname { }
|
||||
| simplename { }
|
||||
| simplename { }
|
||||
|
||||
typedeclaration : classdeclaration { }
|
||||
typedeclaration : classdeclaration { $1 }
|
||||
|
||||
qualifiedname : name DOT IDENTIFIER { }
|
||||
|
||||
simplename : IDENTIFIER { }
|
||||
|
||||
classdeclaration : CLASS IDENTIFIER classbody { }
|
||||
| modifiers CLASS IDENTIFIER classbody { }
|
||||
classdeclaration : CLASS IDENTIFIER classbody { case $3 of (methods, fields) -> Class $2 methods fields }
|
||||
-- | modifiers CLASS IDENTIFIER classbody { case $4 of (methods, fields) -> Class $3 methods fields }
|
||||
|
||||
classbody : LBRACKET RBRACKET { ([], []) }
|
||||
| LBRACKET classbodydeclarations RBRACKET { }
|
||||
| LBRACKET classbodydeclarations RBRACKET { $2 }
|
||||
|
||||
modifiers : modifier { }
|
||||
| modifiers modifier { }
|
||||
| modifiers modifier { }
|
||||
|
||||
classbodydeclarations : classbodydeclaration { }
|
||||
| classbodydeclarations classbodydeclaration{ }
|
||||
classbodydeclarations : classbodydeclaration {
|
||||
case $1 of
|
||||
MethodDecl method -> ([method], [])
|
||||
FieldDecls fields -> ([], fields)
|
||||
}
|
||||
-- | classbodydeclarations classbodydeclaration {
|
||||
-- case ($1, $2) of
|
||||
-- ((methods, fields), MethodDecl method) -> ((methods ++ [method]), fields)
|
||||
-- ((methods, fields), FieldDecl field) -> (methods, (fields ++ [field]))
|
||||
-- }
|
||||
|
||||
modifier : PUBLIC { }
|
||||
| PROTECTED { }
|
||||
| PROTECTED { }
|
||||
| PRIVATE { }
|
||||
| STATIC { }
|
||||
| ABSTRACT { }
|
||||
|
||||
classtype : classorinterfacetype{ }
|
||||
|
||||
classbodydeclaration : classmemberdeclaration { }
|
||||
| constructordeclaration { }
|
||||
classbodydeclaration : classmemberdeclaration { $1 }
|
||||
-- | constructordeclaration { FieldDecl $ VariableDeclaration "int" "a" Nothing } -- TODO
|
||||
|
||||
classorinterfacetype : name{ }
|
||||
|
||||
classmemberdeclaration : fielddeclaration { }
|
||||
| methoddeclaration { }
|
||||
classmemberdeclaration : fielddeclaration { $1 }
|
||||
-- | methoddeclaration { }
|
||||
|
||||
constructordeclaration : constructordeclarator constructorbody { }
|
||||
| modifiers constructordeclarator constructorbody { }
|
||||
| modifiers constructordeclarator constructorbody { }
|
||||
|
||||
fielddeclaration : type variabledeclarators SEMICOLON { }
|
||||
| modifiers type variabledeclarators SEMICOLON { }
|
||||
fielddeclaration : type variabledeclarators SEMICOLON { FieldDecls $ map (convertDeclarator $1) $2 }
|
||||
-- | modifiers type variabledeclarators SEMICOLON {}
|
||||
|
||||
methoddeclaration : methodheader methodbody { }
|
||||
|
||||
block : LBRACKET RBRACKET { }
|
||||
| LBRACKET blockstatements RBRACKET { }
|
||||
| LBRACKET blockstatements RBRACKET { }
|
||||
|
||||
constructordeclarator : simplename LBRACE RBRACE { }
|
||||
| simplename LBRACE formalparameterlist RBRACE { }
|
||||
| simplename LBRACE formalparameterlist RBRACE { }
|
||||
|
||||
constructorbody : LBRACKET RBRACKET { }
|
||||
| LBRACKET explicitconstructorinvocation RBRACKET { }
|
||||
| LBRACKET blockstatements RBRACKET { }
|
||||
| LBRACKET explicitconstructorinvocation blockstatements RBRACKET { }
|
||||
constructorbody : LBRACKET RBRACKET { }
|
||||
| LBRACKET explicitconstructorinvocation RBRACKET { }
|
||||
| LBRACKET blockstatements RBRACKET { }
|
||||
| LBRACKET explicitconstructorinvocation blockstatements RBRACKET { }
|
||||
|
||||
methodheader : type methoddeclarator { }
|
||||
| modifiers type methoddeclarator { }
|
||||
| VOID methoddeclarator { }
|
||||
| modifiers VOID methoddeclarator { }
|
||||
methodheader : type methoddeclarator { }
|
||||
| modifiers type methoddeclarator { }
|
||||
| VOID methoddeclarator { }
|
||||
| modifiers VOID methoddeclarator { }
|
||||
|
||||
type : primitivetype { }
|
||||
| referencetype { }
|
||||
type : primitivetype { $1 }
|
||||
-- | referencetype { }
|
||||
|
||||
variabledeclarators : variabledeclarator { }
|
||||
| variabledeclarators COMMA variabledeclarator { }
|
||||
variabledeclarators : variabledeclarator { [$1] }
|
||||
-- | variabledeclarators COMMA variabledeclarator { $1 ++ [$3] }
|
||||
|
||||
methodbody : block { }
|
||||
| SEMICOLON { }
|
||||
| SEMICOLON { }
|
||||
|
||||
blockstatements : blockstatement { }
|
||||
| blockstatements blockstatement { }
|
||||
| blockstatements blockstatement { }
|
||||
|
||||
formalparameterlist : formalparameter { }
|
||||
| formalparameterlist COMMA formalparameter{ }
|
||||
| formalparameterlist COMMA formalparameter{ }
|
||||
|
||||
explicitconstructorinvocation : THIS LBRACE RBRACE SEMICOLON { }
|
||||
| THIS LBRACE argumentlist RBRACE SEMICOLON { }
|
||||
| THIS LBRACE argumentlist RBRACE SEMICOLON { }
|
||||
|
||||
classtypelist : classtype { }
|
||||
| classtypelist COMMA classtype { }
|
||||
| classtypelist COMMA classtype { }
|
||||
|
||||
methoddeclarator : IDENTIFIER LBRACE RBRACE { }
|
||||
| IDENTIFIER LBRACE formalparameterlist RBRACE { }
|
||||
| IDENTIFIER LBRACE formalparameterlist RBRACE { }
|
||||
|
||||
primitivetype : BOOLEAN { }
|
||||
| numerictype { }
|
||||
primitivetype : BOOLEAN { "boolean" }
|
||||
| numerictype { $1 }
|
||||
|
||||
referencetype : classorinterfacetype { }
|
||||
|
||||
|
||||
variabledeclarator : variabledeclaratorid { }
|
||||
| variabledeclaratorid ASSIGN variableinitializer { }
|
||||
variabledeclarator : variabledeclaratorid { Declarator $1 Nothing }
|
||||
-- | variabledeclaratorid ASSIGN variableinitializer { Declarator $1 Nothing } -- TODO
|
||||
|
||||
blockstatement : localvariabledeclarationstatement { }
|
||||
| statement { }
|
||||
blockstatement : localvariabledeclarationstatement { }
|
||||
| statement { }
|
||||
|
||||
formalparameter : type variabledeclaratorid { }
|
||||
|
||||
argumentlist : expression { }
|
||||
| argumentlist COMMA expression { }
|
||||
| argumentlist COMMA expression { }
|
||||
|
||||
numerictype : integraltype { }
|
||||
numerictype : integraltype { $1 }
|
||||
|
||||
variabledeclaratorid : IDENTIFIER { }
|
||||
variabledeclaratorid : IDENTIFIER { $1 }
|
||||
|
||||
variableinitializer : expression { }
|
||||
|
||||
localvariabledeclarationstatement : localvariabledeclaration SEMICOLON { }
|
||||
|
||||
statement : statementwithouttrailingsubstatement{ }
|
||||
| ifthenstatement { }
|
||||
| ifthenelsestatement { }
|
||||
| whilestatement { }
|
||||
|
||||
| ifthenstatement { }
|
||||
| ifthenelsestatement { }
|
||||
| whilestatement { }
|
||||
|
||||
|
||||
expression : assignmentexpression { }
|
||||
|
||||
integraltype : INT { }
|
||||
| CHAR { }
|
||||
integraltype : INT { "int" }
|
||||
| CHAR { "char" }
|
||||
|
||||
localvariabledeclaration : type variabledeclarators { }
|
||||
|
||||
statementwithouttrailingsubstatement : block { }
|
||||
| emptystatement { }
|
||||
| expressionstatement { }
|
||||
| returnstatement { }
|
||||
| emptystatement { }
|
||||
| expressionstatement { }
|
||||
| returnstatement { }
|
||||
|
||||
ifthenstatement : IF LBRACE expression RBRACE statement { }
|
||||
|
||||
@ -216,55 +223,55 @@ ifthenelsestatement : IF LBRACE expression RBRACE statementnoshortif ELSE state
|
||||
whilestatement : WHILE LBRACE expression RBRACE statement { }
|
||||
|
||||
assignmentexpression : conditionalexpression { }
|
||||
| assignment{ }
|
||||
| assignment{ }
|
||||
|
||||
emptystatement : SEMICOLON { }
|
||||
emptystatement : SEMICOLON { }
|
||||
|
||||
expressionstatement : statementexpression SEMICOLON { }
|
||||
|
||||
returnstatement : RETURN SEMICOLON { }
|
||||
| RETURN expression SEMICOLON { }
|
||||
| RETURN expression SEMICOLON { }
|
||||
|
||||
statementnoshortif : statementwithouttrailingsubstatement { }
|
||||
| ifthenelsestatementnoshortif { }
|
||||
| whilestatementnoshortif { }
|
||||
| ifthenelsestatementnoshortif { }
|
||||
| whilestatementnoshortif { }
|
||||
|
||||
conditionalexpression : conditionalorexpression { }
|
||||
| conditionalorexpression QUESMARK expression COLON conditionalexpression { }
|
||||
| conditionalorexpression QUESMARK expression COLON conditionalexpression { }
|
||||
|
||||
assignment :lefthandside assignmentoperator assignmentexpression { }
|
||||
|
||||
|
||||
|
||||
statementexpression : assignment { }
|
||||
| preincrementexpression { }
|
||||
| predecrementexpression { }
|
||||
| postincrementexpression { }
|
||||
| postdecrementexpression { }
|
||||
| methodinvocation { }
|
||||
| classinstancecreationexpression { }
|
||||
| preincrementexpression { }
|
||||
| predecrementexpression { }
|
||||
| postincrementexpression { }
|
||||
| postdecrementexpression { }
|
||||
| methodinvocation { }
|
||||
| classinstancecreationexpression { }
|
||||
|
||||
ifthenelsestatementnoshortif :IF LBRACE expression RBRACE statementnoshortif
|
||||
ELSE statementnoshortif { }
|
||||
ELSE statementnoshortif { }
|
||||
|
||||
whilestatementnoshortif : WHILE LBRACE expression RBRACE statementnoshortif { }
|
||||
|
||||
conditionalorexpression : conditionalandexpression { }
|
||||
| conditionalorexpression LOGICALOR conditionalandexpression{ }
|
||||
| conditionalorexpression LOGICALOR conditionalandexpression{ }
|
||||
|
||||
lefthandside : name { }
|
||||
|
||||
assignmentoperator : ASSIGN{ }
|
||||
| TIMESEQUAL { }
|
||||
| DIVIDEEQUAL { }
|
||||
| MODULOEQUAL { }
|
||||
| PLUSEQUAL { }
|
||||
| MINUSEQUAL { }
|
||||
| SHIFTLEFTEQUAL { }
|
||||
| SIGNEDSHIFTRIGHTEQUAL { }
|
||||
| UNSIGNEDSHIFTRIGHTEQUAL { }
|
||||
| ANDEQUAL { }
|
||||
| XOREQUAL { }
|
||||
| OREQUAL{ }
|
||||
| TIMESEQUAL { }
|
||||
| DIVIDEEQUAL { }
|
||||
| MODULOEQUAL { }
|
||||
| PLUSEQUAL { }
|
||||
| MINUSEQUAL { }
|
||||
| SHIFTLEFTEQUAL { }
|
||||
| SIGNEDSHIFTRIGHTEQUAL { }
|
||||
| UNSIGNEDSHIFTRIGHTEQUAL { }
|
||||
| ANDEQUAL { }
|
||||
| XOREQUAL { }
|
||||
| OREQUAL{ }
|
||||
|
||||
preincrementexpression : INCREMENT unaryexpression { }
|
||||
|
||||
@ -275,9 +282,9 @@ postincrementexpression : postfixexpression INCREMENT { }
|
||||
postdecrementexpression : postfixexpression DECREMENT { }
|
||||
|
||||
methodinvocation : name LBRACE RBRACE { }
|
||||
| name LBRACE argumentlist RBRACE { }
|
||||
| primary DOT IDENTIFIER LBRACE RBRACE { }
|
||||
| primary DOT IDENTIFIER LBRACE argumentlist RBRACE { }
|
||||
| name LBRACE argumentlist RBRACE { }
|
||||
| primary DOT IDENTIFIER LBRACE RBRACE { }
|
||||
| primary DOT IDENTIFIER LBRACE argumentlist RBRACE { }
|
||||
|
||||
classinstancecreationexpression : NEW classtype LBRACE RBRACE { }
|
||||
| NEW classtype LBRACE argumentlist RBRACE { }
|
||||
@ -286,75 +293,85 @@ conditionalandexpression : inclusiveorexpression { }
|
||||
|
||||
fieldaccess : primary DOT IDENTIFIER { }
|
||||
|
||||
unaryexpression : preincrementexpression { }
|
||||
| predecrementexpression { }
|
||||
| PLUS unaryexpression { }
|
||||
| MINUS unaryexpression { }
|
||||
| unaryexpressionnotplusminus { }
|
||||
unaryexpression : preincrementexpression { }
|
||||
| predecrementexpression { }
|
||||
| PLUS unaryexpression { }
|
||||
| MINUS unaryexpression { }
|
||||
| unaryexpressionnotplusminus { }
|
||||
|
||||
postfixexpression : primary { }
|
||||
| name { }
|
||||
| postincrementexpression { }
|
||||
| postdecrementexpression{ }
|
||||
| name { }
|
||||
| postincrementexpression { }
|
||||
| postdecrementexpression{ }
|
||||
|
||||
primary : primarynonewarray { }
|
||||
primary : primarynonewarray { }
|
||||
|
||||
inclusiveorexpression : exclusiveorexpression { }
|
||||
| inclusiveorexpression OR exclusiveorexpression { }
|
||||
| inclusiveorexpression OR exclusiveorexpression { }
|
||||
|
||||
primarynonewarray : literal { }
|
||||
| THIS { }
|
||||
| LBRACE expression RBRACE { }
|
||||
| THIS { }
|
||||
| LBRACE expression RBRACE { }
|
||||
| classinstancecreationexpression { }
|
||||
| fieldaccess { }
|
||||
| methodinvocation { }
|
||||
| fieldaccess { }
|
||||
| methodinvocation { }
|
||||
|
||||
unaryexpressionnotplusminus : postfixexpression { }
|
||||
| TILDE unaryexpression { }
|
||||
| EXCLMARK unaryexpression { }
|
||||
| castexpression{ }
|
||||
| TILDE unaryexpression { }
|
||||
| EXCLMARK unaryexpression { }
|
||||
| castexpression{ }
|
||||
|
||||
exclusiveorexpression : andexpression { }
|
||||
| exclusiveorexpression XOR andexpression { }
|
||||
| exclusiveorexpression XOR andexpression { }
|
||||
|
||||
literal : INTLITERAL { }
|
||||
| BOOLLITERAL { }
|
||||
| CHARLITERAL { }
|
||||
| STRINGLITERAL { }
|
||||
| JNULL { }
|
||||
literal : INTLITERAL { }
|
||||
| BOOLLITERAL { }
|
||||
| CHARLITERAL { }
|
||||
| JNULL { }
|
||||
|
||||
castexpression : LBRACE primitivetype RBRACE unaryexpression { }
|
||||
| LBRACE expression RBRACE unaryexpressionnotplusminus{ }
|
||||
castexpression : LBRACE primitivetype RBRACE unaryexpression { }
|
||||
| LBRACE expression RBRACE unaryexpressionnotplusminus{ }
|
||||
|
||||
andexpression : equalityexpression { }
|
||||
| andexpression AND equalityexpression { }
|
||||
| andexpression AND equalityexpression { }
|
||||
|
||||
equalityexpression : relationalexpression { }
|
||||
| equalityexpression EQUAL relationalexpression { }
|
||||
| equalityexpression NOTEQUAL relationalexpression { }
|
||||
| equalityexpression EQUAL relationalexpression { }
|
||||
| equalityexpression NOTEQUAL relationalexpression { }
|
||||
|
||||
relationalexpression : shiftexpression { }
|
||||
| relationalexpression LESS shiftexpression { }
|
||||
| relationalexpression GREATER shiftexpression { }
|
||||
| relationalexpression LESSEQUAL shiftexpression { }
|
||||
| relationalexpression GREATEREQUAL shiftexpression { }
|
||||
| relationalexpression INSTANCEOF referencetype { }
|
||||
| relationalexpression LESS shiftexpression { }
|
||||
| relationalexpression GREATER shiftexpression { }
|
||||
| relationalexpression LESSEQUAL shiftexpression { }
|
||||
| relationalexpression GREATEREQUAL shiftexpression { }
|
||||
| relationalexpression INSTANCEOF referencetype { }
|
||||
|
||||
shiftexpression : additiveexpression { }
|
||||
shiftexpression : additiveexpression { }
|
||||
|
||||
additiveexpression : multiplicativeexpression { }
|
||||
| additiveexpression PLUS multiplicativeexpression { }
|
||||
| additiveexpression MINUS multiplicativeexpression { }
|
||||
| additiveexpression PLUS multiplicativeexpression { }
|
||||
| additiveexpression MINUS multiplicativeexpression { }
|
||||
|
||||
multiplicativeexpression : unaryexpression { }
|
||||
| multiplicativeexpression MUL unaryexpression { }
|
||||
| multiplicativeexpression DIV unaryexpression { }
|
||||
| multiplicativeexpression MOD unaryexpression { }
|
||||
| multiplicativeexpression MUL unaryexpression { }
|
||||
| multiplicativeexpression DIV unaryexpression { }
|
||||
| multiplicativeexpression MOD unaryexpression { }
|
||||
|
||||
|
||||
{
|
||||
|
||||
data MethodOrFieldDeclaration = MethodDecl MethodDeclaration
|
||||
| FieldDecls [VariableDeclaration]
|
||||
|
||||
data Declarator = Declarator Identifier (Maybe Expression)
|
||||
|
||||
-- convertDeclaratorList :: [DataType] -> MethodOrFieldDeclaration
|
||||
-- convertDeclaratorList = FieldDecls $ map
|
||||
|
||||
convertDeclarator :: DataType -> Declarator -> VariableDeclaration
|
||||
convertDeclarator dataType (Declarator id assigment) = VariableDeclaration dataType id assigment
|
||||
|
||||
parseError :: [Token] -> a
|
||||
parseError _ = error "Parse error"
|
||||
parseError msg = error ("Parse error: " ++ show msg)
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
{
|
||||
module Parser.Lexer(Token(..), alexScanTokens) where
|
||||
module Parser.Lexer(Token(..), alexScanTokens) where
|
||||
import Text.Read
|
||||
}
|
||||
|
||||
%wrapper "basic"
|
||||
@ -7,18 +8,221 @@
|
||||
$digit = 0-9
|
||||
$alpha = [a-zA-Z]
|
||||
$alphanum = [a-zA-Z0-9]
|
||||
$JavaLetter = [A-Za-z\_\$]
|
||||
$JavaLetterOrDigit = [A-Za-z\_\$0-9]
|
||||
|
||||
tokens :-
|
||||
$white ;
|
||||
"/*"(.|\n)*"*/" { \s -> Comment s }
|
||||
"//".* {\s -> Comment s}
|
||||
|
||||
"/*"(.|\n)*"*/" ;
|
||||
"//".* ;
|
||||
-- keywords
|
||||
"abstract" { \_ -> ABSTRACT }
|
||||
"assert" { \_ -> BOOLEAN }
|
||||
"boolean" { \_ -> BOOLEAN}
|
||||
"break" { \_ -> BREAK}
|
||||
"byte" { \_ -> BYTE}
|
||||
"case" { \_ -> CASE}
|
||||
"catch" { \_ -> CATCH}
|
||||
"char" { \_ -> CHAR}
|
||||
"class" { \_ -> CLASS}
|
||||
"const" { \_ -> CONST}
|
||||
"continue" { \_ -> CONTINUE}
|
||||
"default" { \_ -> DEFAULT}
|
||||
"do" { \_ -> DO}
|
||||
"double" { \_ -> DOUBLE}
|
||||
("else"|"ifn't") { \_ -> ELSE}
|
||||
"enum" { \_ -> ENUM}
|
||||
"extends" { \_ -> EXTENDS}
|
||||
"final" { \_ -> FINAL}
|
||||
"finally" { \_ -> FINALLY}
|
||||
"float" { \_ -> FLOAT}
|
||||
"for" { \_ -> FOR}
|
||||
"if" { \_ -> IF}
|
||||
"goto" { \_ -> GOTO}
|
||||
"implements" { \_ -> IMPLEMENTS}
|
||||
"import" { \_ -> IMPORT}
|
||||
"instanceof" { \_ -> INSTANCEOF}
|
||||
"int" { \_ -> INT}
|
||||
"long" { \_ -> LONG}
|
||||
"native" { \_ -> NATIVE}
|
||||
"new" { \_ -> NEW}
|
||||
"package" { \_ -> PACKAGE}
|
||||
"private" { \_ -> PRIVATE}
|
||||
"protected" { \_ -> PROTECTED}
|
||||
"public" { \_ -> PUBLIC}
|
||||
"return" { \_ -> RETURN}
|
||||
"short" { \_ -> SHORT}
|
||||
"static" { \_ -> STATIC}
|
||||
"strictfp" { \_ -> STRICTFP}
|
||||
"super" { \_ -> SUPER}
|
||||
"switch" { \_ -> SWITCH}
|
||||
"synchronized" { \_ -> SYNCHRONIZED}
|
||||
"this" { \_ -> THIS}
|
||||
"throw" { \_ -> THROW}
|
||||
"throws" { \_ -> THROWS}
|
||||
"transient" { \_ -> TRANSIENT}
|
||||
"try" { \_ -> TRY}
|
||||
"void" { \_ -> VOID}
|
||||
"volatile" { \_ -> VOLATILE}
|
||||
"while" { \_ -> WHILE}
|
||||
-- Literals
|
||||
"true" { \_ -> BOOLLITERAL True }
|
||||
"false" { \_ -> BOOLLITERAL False }
|
||||
"null" { \_ -> NULLLITERAL }
|
||||
-- end keywords
|
||||
$JavaLetter$JavaLetterOrDigit* { \s -> IDENTIFIER s }
|
||||
-- Literals
|
||||
[1-9]([0-9\_]*[0-9])* { \s -> case readMaybe $ filter ((/=) '_') s of Just a -> INTEGERLITERAL a; Nothing -> error ("failed to parse INTLITERAL " ++ s) }
|
||||
"'"."'" { \s -> case (s) of _ : c : _ -> CHARLITERAL c; _ -> error ("failed to parse CHARLITERAL " ++ s) }
|
||||
-- separators
|
||||
"(" { \_ -> LBRACE }
|
||||
")" { \_ -> RBRACE }
|
||||
"{" { \_ -> LBRACKET }
|
||||
"}" { \_ -> RBRACKET }
|
||||
";" { \_ -> SEMICOLON }
|
||||
"," { \_ -> COMMA}
|
||||
"." { \_ -> DOT }
|
||||
-- operators
|
||||
"=" { \_ -> ASSIGN }
|
||||
"==" { \_ -> EQUAL }
|
||||
"+" { \_ -> PLUS }
|
||||
"+=" { \_ -> PLUSEQUAL }
|
||||
">" { \_ -> GREATER }
|
||||
">=" { \_ -> GREATEREQUAL }
|
||||
"-" { \_ -> MINUS }
|
||||
"-=" { \_ -> MINUSEQUAL }
|
||||
"<" { \_ -> LESS }
|
||||
"<=" { \_ -> LESSEQUAL }
|
||||
"*" { \_ -> TIMES }
|
||||
"*=" { \_ -> TIMESEQUAL }
|
||||
"!" { \_ -> NOT }
|
||||
"!=" { \_ -> NOTEQUAL }
|
||||
"/" { \_ -> DIV }
|
||||
"/=" { \_ -> DIVEQUAL }
|
||||
"~" { \_ -> BITWISENOT }
|
||||
"&&" { \_ -> AND }
|
||||
"&" { \_ -> BITWISEAND }
|
||||
"&=" { \_ -> ANDEQUAL }
|
||||
"?" { \_ -> QUESTIONMARK }
|
||||
"||" { \_ -> OR }
|
||||
"|" { \_ -> BITWISEOR }
|
||||
"|=" { \_ -> OREQUAL }
|
||||
":" { \_ -> COLON }
|
||||
"++" { \_ -> INCREMENT }
|
||||
"^" { \_ -> XOR }
|
||||
"^=" { \_ -> XOREQUAL }
|
||||
"--" { \_ -> DECREMENT }
|
||||
"%" { \_ -> MODULO }
|
||||
"%=" { \_ -> MODULOEQUAL }
|
||||
"<<" { \_ -> SHIFTLEFT }
|
||||
"<<=" { \_ -> SHIFTLEFTEQUAL }
|
||||
">>" { \_ -> SHIFTRIGHT }
|
||||
">>=" { \_ -> SHIFTRIGHTEQUAL }
|
||||
">>>" { \_ -> UNSIGNEDSHIFTRIGHT }
|
||||
">>>=" { \_ -> UNSIGNEDSHIFTRIGHTEQUAL }
|
||||
|
||||
|
||||
{
|
||||
data Token
|
||||
= Comment String
|
||||
| Different
|
||||
= ABSTRACT
|
||||
| ASSERT
|
||||
| BOOLEAN
|
||||
| BREAK
|
||||
| BYTE
|
||||
| CASE
|
||||
| CATCH
|
||||
| CHAR
|
||||
| CLASS
|
||||
| CONST
|
||||
| CONTINUE
|
||||
| DEFAULT
|
||||
| DO
|
||||
| DOUBLE
|
||||
| ELSE
|
||||
| ENUM
|
||||
| EXTENDS
|
||||
| FINAL
|
||||
| FINALLY
|
||||
| FLOAT
|
||||
| FOR
|
||||
| IF
|
||||
| GOTO
|
||||
| IMPLEMENTS
|
||||
| IMPORT
|
||||
| INSTANCEOF
|
||||
| INT
|
||||
| INTERFACE
|
||||
| LONG
|
||||
| NATIVE
|
||||
| NEW
|
||||
| PACKAGE
|
||||
| PRIVATE
|
||||
| PROTECTED
|
||||
| PUBLIC
|
||||
| RETURN
|
||||
| SHORT
|
||||
| STATIC
|
||||
| STRICTFP
|
||||
| SUPER
|
||||
| SWITCH
|
||||
| SYNCHRONIZED
|
||||
| THIS
|
||||
| THROW
|
||||
| THROWS
|
||||
| TRANSIENT
|
||||
| TRY
|
||||
| VOID
|
||||
| VOLATILE
|
||||
| WHILE
|
||||
| IDENTIFIER String
|
||||
| INTEGERLITERAL Int
|
||||
| CHARLITERAL Char
|
||||
| BOOLLITERAL Bool
|
||||
| NULLLITERAL
|
||||
| LBRACE
|
||||
| RBRACE
|
||||
| LBRACKET
|
||||
| RBRACKET
|
||||
| SEMICOLON
|
||||
| COMMA
|
||||
| DOT
|
||||
| ASSIGN
|
||||
| EQUAL
|
||||
| PLUS
|
||||
| PLUSEQUAL
|
||||
| GREATER
|
||||
| GREATEREQUAL
|
||||
| MINUS
|
||||
| MINUSEQUAL
|
||||
| LESS
|
||||
| LESSEQUAL
|
||||
| TIMES
|
||||
| TIMESEQUAL
|
||||
| NOT
|
||||
| NOTEQUAL
|
||||
| DIV
|
||||
| DIVEQUAL
|
||||
| BITWISENOT
|
||||
| AND
|
||||
| BITWISEAND
|
||||
| ANDEQUAL
|
||||
| QUESTIONMARK
|
||||
| OR
|
||||
| BITWISEOR
|
||||
| OREQUAL
|
||||
| COLON
|
||||
| INCREMENT
|
||||
| XOR
|
||||
| XOREQUAL
|
||||
| DECREMENT
|
||||
| MODULO
|
||||
| MODULOEQUAL
|
||||
| SHIFTLEFT
|
||||
| SHIFTLEFTEQUAL
|
||||
| SHIFTRIGHT
|
||||
| SHIFTRIGHTEQUAL
|
||||
| UNSIGNEDSHIFTRIGHT
|
||||
| UNSIGNEDSHIFTRIGHTEQUAL
|
||||
deriving(Eq,Show)
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user