精品深夜AV无码一区二区_伊人久久无码中文字幕_午夜无码伦费影视在线观看_伊人久久无码精品中文字幕

代做EECE 6083、c/c++設計程序代寫

時間:2024-04-11  來源:  作者: 我要糾錯



EECE 6083/5183 Compiler Project
1 Compiler Project
The class project is to build a simple recursive decent (LL(1)) compiler by hand (not using compiler
construction tools such as flex or antlr). You can use any imperative block structured programming language that supports recursion and for which I can install a standard debian package to
test your solution on my computer. Examples of languages that students have used for this class
include: c, c++, go, rust, java, and python. If you are not certain that your desired programming language is ok, please check with me. While you can use a wide selection of languages, you
cannot use any language features for constructing compiler subsystems (regular expression parsers,
etc). That said, I encourage you to use some of the more complex builtin data structures of these
languages such as hash tables. Again, if you have questions about what you can and cannot do,
please ask.
In addition to sending me your compiler source and build environment that I can run on my
Linux workstation (you are responsible for ensuring that it will build on a standard Linux box; if
you build it on some exotic system like Haiku, we can discuss a demo on that platform), you must
also turn in a one page report documenting your compiler. It should document your software, its
structure, the build process, and the language features that are correctly implemented as well as
those elements of the compiler that are not completed. Finally, the report should also highlight
any unique features you have implemented in the system.
I have organized the compiler project into 5 development phases with deadlines scattered
throughout the course semester period. While these deadline are soft, I will use your history
of early/late to assign plus/minus graduations to your final grade. I encourage you to attempt to
complete these phases early.
January 2, 2024 – 12 : 28 1
EECE 6083/5183 Compiler Project
2 Lexical Analysis: The Scanner
2.1 Tokens
Lexical analysis involves converting strings in the input language to tokens. Here is a representative
example of the object type for tokens.
// a globally visible enumeration (needed by both the lexer and by the parser
enum tokenType = {PLUS, MINUS, IF_RW, LOOP_RW, END_RW, L_PAREN, R_PAREN,
L_BRACKET, R_BRACKET, ... , NUMBER, IDENTIFIER}
class token
tokenType: tt
tokenMark: tm
end class
The token mark can be a complex data type that records secondary information about the token.
For many token types (e.g., PLUS) there is no token mark data required, the token type value fully
characterizes the token. For other token types, (e.g., IDENTIFIER) the token mark will contain
additional information to characterize the token; initially this will mostly be to hold an identifier
string, but later it may well contain information about complex types such as functions/procedures
and their argument list signature/return type, etc. In some systems, a compiler might combine
arithmetic operators, relational operators, multiplier operators, etc into a common token type and
use the token mark to record the specific member of that token class that is being represented.
2.2 Supporting functions/objects
There are some key support functions that can make building the compiler much easier; especially if
you encapsulate them with a strong API that permits the restructuring/extension of the underlying
implementation. I will organize these support functions into 3 parts: (i) input processing, (ii)
warning and error reporting, and (iii) symbol table management and reserved word setup. Below I
will present suggestions for each of these components. You are not required to setup your solution
this way, these are simply my recommendations to you. I will document each of these in an
object-oriented basis, you are not required to setup/use an object-oriented language, this is just a
convenient way for me to present the ideas.
2.2.1 Input Processing
I recommend that you create an object to manage your input file setup and location recording
(what line in the file is currently being processed). This might be a bit much for this project, but
it helps encapsulate stuff related to the input file being processed. It is a good plan to build it this
way as if you ever move to a more complicated language where multiple files are processed while
processing the designated input file, it is easy to have a stack of file points/line count variables to
record where the system is in processing the various files required.
January 2, 2024 – 12 : 28 2
EECE 6083/5183 Compiler Project
In general the lineCnt variable will be used to record which line in the input file the scanner
is currently working on. In this project, this value is used primarily to help generate meaningful
error messages.
class inFile
private:
file: filePtr = null // the input file
string: fileName
int: lineCnt = 0 // the line count; initialized to zero
public:
bool: attachFile(string) // open the named file
char: getChar() // get the next character
void: ungetChar(char) // push character back to the input file string
void: incLineCnt()
void: getLineCnt()
end class
2.2.2 Warning and Error Reporting
The main program should have an object for reporting errors and warnings. Ideally these functions
will output error messages using a standard format (e.g., https://gcc.gnu.org/onlinedocs/
gcc-3.3.6/gnat_ug_unx/Output-and-Error-Message-Control.html that supporting tools such
as emacs can use to, for example, automatically position your text editor/IDE to the correct file
and line number corresponding to the warning/error. The API for this is fairly simple.
class reporting
private:
bool: errorStatus = False // true if the compiler has discovered an error
public
void reportError(char *message)
void reportWarning(char *message)
bool getErrorStatus()
end class
While a compiler attempts to continue in the presence of both errors and warnings, an error
condition will generally cause the compiler to proceed only with the parse and type checking phases;
code optimization and generation should not occur when errors are encountered in the parsing of
the input program. In general the reportError function will set the private variable errorStatus
to True.
2.2.3 Symbol Table Management/Reserved Words
Most compilers will use a hash table(s) of the symbols seen in the input file; this is called the
symbol table. These symbols would be identifiers and functions. This is also a convenient place to
January 2, 2024 – 12 : 28 3
EECE 6083/5183 Compiler Project
drop entries for the reserved words in the language (such as if, loop, end, and so on). The symbol
table will be revised and extended as you build latter parts of the compiler, so it is imperative that
you keep access to it setup through and API so that its actual implementation is easily modified
later. The hashLook function will look into the symbol table and return the token for the string
argument. If this the first time an entry to the symbol table occurs for this string, then a new
entry is created with a default token definition (generally IDENTIFIER).
class symbolTable
private:
hashTable<token>: symTab
public:
token: hashLook(string) // lookup the string in the hash table
void: setToken(string) // change the token values for this symbol
end class
In general the lexer will lookup every candidate identifier string in the symbol table and return
the token stored in the symbol table for that string. Thus, to make life easy, a good idea is to preseed the symbol table with the reserved word strings and setup the tokens for each so that instead
of returning the token IDENTIFIER, the correct token for that reserved word is returned. Thus,
before you start processing the file, you will build a simple look to iterate through the reserved
word strings in order to initialize the symbol table with the reserved word tokens.
Constants
So the question sometimes comes up, how do we treat strings and numerical values in the lexical
analysis phase. There is no single uniform answer to this. You can treat them: (i) directly as
tokens, (ii), register them in the symbol table, or, (iii) build a separate string/numeric table(s)1
to
store the token representation of the item. If we assume that the lexer match string for the token is
stored as an ASCII string in the variable tokenString, then examples of the lexer return code for
each of these options can be outlined as (showing both for a STRING token and for an INTEGER
token):
(i) return new token(STRING, tokenString)
return new token(INTEGER, atoi(tokenString))
(ii) tok = symbolTable.hashLook(tokenString)
if (tok.tt != STRING) { tok.tt = STRING }
return tok
tok = symbolTable.hashLook(tokenString)
1Either a single common constantTable for both, or having two separate tables, one for strings and one for numerics
is possible.
January 2, 2024 – 12 : 28 4
EECE 6083/5183 Compiler Project
if (tok.tt != INTEGER) { tok.tt = INTEGER }
// optionally we might also build/add the integer value to the token
return tok
(iii) return new token(STRING, constantTable.hashLook(tokenString))
return new token(INTEGER, constantTable.hashLook(tokenString))
Of course there are many variations on this coding example. The option of using the symbol table
or a separate constant table is a good way to compress the final storage map. That is, if you store
them in the symbol table, then (at each scope) common constants will be represented as one item
that has to be mapped into memory during the code generation phase. If instead, you store all
constants in constant table(s) that transcend all scopes, you can potentially reduce the storage map
size even further.
2.3 The Scanner
I recommend that you build a scanner object with the principle API call scan() that returns the
next token in the input file. Normally your parser will call the scan() function to get the next
token to determine the next course of action for the parser. When the file has advanced to the end
of the file, you should have an end-of-file (EOF) token that can be returned to the parser.
For purposes of this step of your compiler, I recommend that you build a main program that
initializes the symbol table and iteratively calls scan() until the end-of-file is reached.
The scanner must skip white-space, newlines, tabs, and comments; comments are start with the
string ”//” and continue to the next newline character. It should count newlines to aid the error
reporting functions.
Illegal characters should be treated as white-space separators and reported as errors. These errors should not stop the parser or semantic analysis phases, but they should prevent code generation
from occurring.
The tokens your scanner should recognize are the tokens found in the project language specification.
I would also recommend defining character classes to streamline your scanner definition. In
short, what this means is you should define an array indexed by the input character that maps an
ASCII character into a character class. For example mapping all the digits [0-9] into the digit
character class, letters [a-zA-Z] into the letter character class, and so on (of course you have to
define the character classes in some enumeration type. I will go over this more in class for you.
I am leaving the remainder of this section in place; it is from an earlier version of
this document that may or may not be helpful to you.
While the scanner can be constructed to recognize reserved words and identifiers separately,
I strongly recommend that you fold them together as a common case in your scanner and seed
the symbol table with the reserved words and their corresponding token type. More precisely, I
recommend that you incorporate a rudimentary symbol table into your initial scanner implementation. While the data types of the symbol table entries are likely to expand as you build additional
capabilities into your compiler, initially you can have the symbol table entries record the token
January 2, 2024 – 12 : 28 5
EECE 6083/5183 Compiler Project
type and have a pointer to the string for the identifier/reserved word. For example, each element
in your symbol table could have the following structure:
sym_table_entry : record
token_type : TOKEN_TYPES;
token_string : *char;
end record
where TOKEN TYPES is the enumeration type of all your token types.
Operationally, I would build the symbol table so that new entries are created with the token type
field initialized to IDENTIFIER. You can then seed the symbol table (during the scanner initialization step described above) with reserved words in the scanner’s initialize method. The easiest
way to do this is to setup an array of reserved word and their token type. Then walk through the
array to do a hash look up with each reserved word string and change the token type field to the
specified token type. We will go over this in class.
January 2, 2024 – 12 : 28 6
EECE 6083/5183 Compiler Project
3 The Parser
Build a recursive decent parser that looks only at the immediate next token to control the parse.
That is, build an LL(1) parser from the project programming language specification given elsewhere
in these webpages. If you really would prefer to build a LALR parser that is possible, but please
discuss it with me first.
The parser should have at least one resync point to try to recover from a parsing error.
January 2, 2024 – 12 : 28 7
EECE 6083/5183 Compiler Project
4 Type Checking
Incorporate type checking into the parser and perform type checking while the statements are
parsed. Your principle concern is with scoping and type matching. At least for expressions and
statements, your parsing rules will now have to be expanded to return the type result for the
construct just parsed. The upper rules will use that type information to assert type checks at its
level.
A full symbol table complete with scoping data must be constructed. You must be able to
define a scope and remove a scope as the parse is made. You can achieve scoping by having nested
symbol tables or by chaining together the entries in the symbol table and placing scope entry points
that can be used to control how symbols are removed when your parser leaves a scope.
January 2, 2024 – 12 : 28 8
EECE 6083/5183 Compiler Project
5 Code Generation
You have two options for code generation. The first (and recommended) option is to use the LLVM
back-end optimizer and code generator. In this case your code generation phase would really be a
translator to the LLVM intermediate form (either the memory resident IR or the llvm assembly).
The second option is to generate a file containing a restricted C program space as documented
below.
5.1 Generating C
Basically the generated file should have declarations for your memory space, register space and a
flat C (no subroutines) with goto’s used to branch around the generated C file.
Your generated C must follow the style of a load/store architecture. You may assume a register
file sized to your largest need and a generic 2-address instruction format. You do not have to
worry about register allocation and you should not carryover register/variable use from expression
to expression. Thus a program with two expressions:
c := a + b;
d := a + c + b;
would generate something like:
// c := a + b;
R[1] = MM[44]; // assumes variable a is at MM location 44
R[2] = MM[56]; // assumes variable b is at MM location 56
R[3] = R[1] + R[2];
MM[32] = R[3]; // assumes variable c is at MM location 32
// d := a + c + b;
R[1] = MM[44];
R[2] = MM[32];
R[3] = R[1] + R[2];
R[4] = MM[56];
R[5] = R[3] + R[4];
MM[144] = R[5]; // assumes variable d is at MM location 144
You can also use indirection off the registers to define memory locations to load into registers.
For example your code generator can generate something like this:
R[1] = MM[R[0]+4];
You can statically allocate/assign some of the registers for specific stack operation (pointers).
The stack must be built in your memory space.
For conditional branching (goto) you can use an if statement with a then clause but not with
an else clause. Furthermore the condition must be evaluated to true/false (0/1) prior to the if
statement so that the condition in the if statement is limited to a simple comparison to true/false.
Thus for conditional branching only this form of an if statement is permitted:
January 2, 2024 – 12 : 28 9
EECE 6083/5183 Compiler Project
if (R[2] = true) then goto label;
The code generator is to output a restricted form of C that looks much like a 3-address load/store
architecture. You can assume an unbounded set of registers, a 64M bytes of memory space containing space for static memory and stack memory. Your machine code should look something like
(I forget C syntax, so you may have to translate this to real C):
Reg[3] = MM[Reg[SP]];
Reg[SP] = Reg[SP] { 2;
Reg[4] = MM[12]; // assume a static
// variable at
// location 12
Reg[5] = Reg[3] + Reg[4]
MM[12] = Reg[5];
You must use simple C: assignment statements, goto statements, and if statements. No procedures, switch statements, etc.
You must evaluate the conditional expressions in “if statements” and simply reference the result
(stored in a register) in the if statement of your generated C code.
Basically you should generate C code that looks like a simple 3-address assembly language.
5.2 Generating LLVM Assembly
See other lecture notes on LLVM.
5.3 Activation Records
See other lecture notes on Code Generation and Figure 1.
January 2, 2024 – 12 : 28 10
EECE 6083/5183 Compiler Project
FP
SP
return address
arg 2
local var 1
local var 2
arg 1
return value ptr
old SP
old FP
old FP
old SP
FP: frame pointer
SP: stack pointer Activation record k+1 Activation record k
prev
next
prev
next
Activation record k Activation record k+1
Curr activation record
Figure 1: The call chain of activation records; stack model on left and heap model on right
January 2, 2024 – 12 : 28 11
EECE 6083/5183 Compiler Project
6 Runtime
If you are using the LLVM infrastructure, you can use the libc supported gets, puts, atoi, etc
functions as your runtime system. This means that you will not end up writing the runtime library
other than adapting the code generator to interface to the libc standard.
For the runtime environment, you should enter the runtime function names and type signatures
into your symbol table prior to starting the parse of the input files. To code generate for these
functions, you can either special case them and use C function calls or you can have a static
(handwritten) C program with predefined labels (on the hand written code C code that calls your
library functions) that you generated code can goto. This second option sounds more difficult but
is probably much easier to implement as it’s not a special case in your code generator.
There are several (globally visible) predefined procedures provided by the runtime support
environment, namely the functions described in the project language description.
January 2, 2024 – 12 : 28 12

請加QQ:99515681  郵箱:[email protected]   WX:codinghelp






 

標簽:

掃一掃在手機打開當前頁
  • 上一篇:代寫COP4600 File Systems編程代做
  • 下一篇:代寫股票公式 代寫通達信指標 代做公式
  • 無相關信息
    昆明生活資訊

    昆明圖文信息
    蝴蝶泉(4A)-大理旅游
    蝴蝶泉(4A)-大理旅游
    油炸竹蟲
    油炸竹蟲
    酸筍煮魚(雞)
    酸筍煮魚(雞)
    竹筒飯
    竹筒飯
    香茅草烤魚
    香茅草烤魚
    檸檬烤魚
    檸檬烤魚
    昆明西山國家級風景名勝區
    昆明西山國家級風景名勝區
    昆明旅游索道攻略
    昆明旅游索道攻略
  • 短信驗證碼平臺 理財 WPS下載

    關于我們 | 打賞支持 | 廣告服務 | 聯系我們 | 網站地圖 | 免責聲明 | 幫助中心 | 友情鏈接 |

    Copyright © 2025 kmw.cc Inc. All Rights Reserved. 昆明網 版權所有
    ICP備06013414號-3 公安備 42010502001045

    精品深夜AV无码一区二区_伊人久久无码中文字幕_午夜无码伦费影视在线观看_伊人久久无码精品中文字幕
    <samp id="e4iaa"><tbody id="e4iaa"></tbody></samp>
    <ul id="e4iaa"></ul>
    <blockquote id="e4iaa"><tfoot id="e4iaa"></tfoot></blockquote>
    • <samp id="e4iaa"><tbody id="e4iaa"></tbody></samp>
      <ul id="e4iaa"></ul>
      <samp id="e4iaa"><tbody id="e4iaa"></tbody></samp><ul id="e4iaa"></ul>
      <ul id="e4iaa"></ul>
      <th id="e4iaa"><menu id="e4iaa"></menu></th>
      国产亚洲成av人在线观看导航 | 丝袜美腿亚洲综合| 国产一区二区精品在线观看| 欧美精品自拍偷拍动漫精品| 亚洲国产aⅴ天堂久久| 日本精品免费观看高清观看| 一区二区三区丝袜| 欧美日韩精品一区二区三区四区| 亚洲欧美另类小说| 欧美日韩亚洲国产综合| 日韩精品亚洲专区| 久久久噜噜噜久久中文字幕色伊伊| 国产综合色在线| 国产精品日产欧美久久久久| 色哟哟国产精品| 污片在线观看一区二区| 欧美一区二区成人| 成人永久aaa| 一区二区三区精品视频| 91精品国产综合久久久久久漫画 | 成人免费视频app| 亚洲日本在线天堂| 欧美另类久久久品| 国产精品一二三四五| 亚洲精品视频一区二区| 91精品国产91久久久久久最新毛片 | 国产盗摄一区二区| 欧美极品aⅴ影院| 欧美日本一区二区三区四区| 久久91精品国产91久久小草| 亚洲图片激情小说| 精品捆绑美女sm三区| 91麻豆精品一区二区三区| 美腿丝袜亚洲一区| 亚洲综合小说图片| 国产欧美日韩卡一| 欧美精品高清视频| 91视频精品在这里| 懂色av一区二区在线播放| 日本欧美大码aⅴ在线播放| 国产精品不卡一区| 欧美日韩一区二区在线观看视频 | 久久亚洲一级片| 欧美色男人天堂| 成人午夜精品在线| 美女一区二区三区| 亚洲午夜在线电影| 成人欧美一区二区三区1314| 欧美精品一区二区高清在线观看| 色国产综合视频| 成人精品一区二区三区中文字幕| 久久精品国产久精国产爱| 亚洲成人精品一区| 亚洲一二三级电影| 日韩一区中文字幕| 国产精品欧美综合在线| 国产日产精品一区| 久久久国产午夜精品| 精品美女在线播放| 久久伊人蜜桃av一区二区| 日韩欧美国产电影| 欧美一级日韩免费不卡| 在线不卡免费欧美| 这里是久久伊人| 日韩欧美在线123| 精品国产123| 国产欧美一区二区精品婷婷| 久久免费偷拍视频| 国产欧美日韩亚州综合 | 欧美国产日韩一二三区| 国产午夜亚洲精品理论片色戒 | 欧美日韩高清在线| 欧美精品一二三区| 欧美一级久久久久久久大片| 欧美一区二区三区视频免费| 91精品婷婷国产综合久久竹菊| 欧美另类高清zo欧美| 欧美一区日本一区韩国一区| 日韩欧美国产一区二区在线播放 | 日韩一级片在线播放| 欧美成人一级视频| 久久久久国产精品人| 欧美国产一区在线| 亚洲色欲色欲www在线观看| 中文字幕亚洲一区二区av在线 | 国产欧美一区二区三区在线老狼| 精品国产伦一区二区三区观看方式 | 亚洲激情图片小说视频| 性做久久久久久免费观看| 美国十次综合导航| 成人动漫视频在线| 欧美日韩在线直播| 久久久精品综合| 国产精品系列在线| 五月综合激情婷婷六月色窝| 久久精品免费看| av电影一区二区| 欧美一区日本一区韩国一区| 国产三级欧美三级日产三级99 | 欧美日韩一卡二卡三卡| 精品国产伦一区二区三区观看方式 | 色美美综合视频| 日韩精品中文字幕在线不卡尤物| 久久无码av三级| 亚洲线精品一区二区三区八戒| 蜜桃视频在线一区| 99re热这里只有精品视频| 91精品国产综合久久精品| 国产欧美日本一区二区三区| 亚洲国产精品一区二区久久恐怖片 | 国产精品久久久久影院| 日韩综合一区二区| www.日本不卡| 欧美电视剧在线看免费| 亚洲乱码中文字幕综合| 国产一区二区剧情av在线| 欧美日本一区二区三区| 亚洲欧洲日韩在线| 国产真实精品久久二三区| 欧美日韩成人综合在线一区二区| 久久久精品中文字幕麻豆发布| 亚洲一二三区视频在线观看| 丁香婷婷综合激情五月色| 日韩三区在线观看| 亚洲成人动漫一区| 色播五月激情综合网| 欧美大尺度电影在线| 亚洲一区日韩精品中文字幕| 国产成人高清在线| 精品久久久久香蕉网| 日韩福利电影在线| 欧美精品一卡二卡| 午夜免费欧美电影| 欧美日韩一区不卡| 亚洲v精品v日韩v欧美v专区 | 激情综合色丁香一区二区| 欧美狂野另类xxxxoooo| 亚洲国产视频一区| 欧美在线免费观看亚洲| 亚洲人成小说网站色在线| av在线不卡电影| 最新不卡av在线| 91久久精品国产91性色tv| 伊人夜夜躁av伊人久久| 色吊一区二区三区| 亚洲第一激情av| 91精品视频网| 激情小说亚洲一区| 国产午夜亚洲精品羞羞网站| 成人污污视频在线观看| 亚洲欧洲国产专区| 欧美性生活久久| 日本视频在线一区| 精品久久久久久最新网址| 国产成人在线免费| 18成人在线视频| 一本久道久久综合中文字幕| 亚洲第一主播视频| 精品精品国产高清一毛片一天堂| 国产一区二区精品久久99| 中文字幕乱码亚洲精品一区| 色综合天天综合网国产成人综合天| 一区二区三区在线免费播放| 欧美精品v日韩精品v韩国精品v| 奇米在线7777在线精品| 久久久国产一区二区三区四区小说| 不卡的电影网站| 亚洲a一区二区| 国产午夜精品一区二区三区嫩草| 99国产精品久| 蜜臀精品久久久久久蜜臀| 欧美激情综合在线| 欧美猛男gaygay网站| 国内精品国产成人| 一区二区三区四区蜜桃| 精品国产乱码久久久久久蜜臀| 成人一区二区三区在线观看 | 亚洲视频小说图片| 欧美夫妻性生活| 菠萝蜜视频在线观看一区| 亚洲成人一区二区| 中文字幕av一区二区三区| 7878成人国产在线观看| 不卡的av中国片| 蜜桃av噜噜一区| 一区二区三区四区亚洲| 国产亚洲精品aa午夜观看| 欧美日韩精品一区二区天天拍小说| 国产精品一级在线| 亚洲国产精品尤物yw在线观看| 久久精品在线观看| 日韩一级大片在线观看| 91蜜桃视频在线| 国产xxx精品视频大全| 日韩**一区毛片| 一区二区三区欧美日| 国产精品区一区二区三| 欧美v日韩v国产v| 欧美日韩精品久久久| 色综合久久久久久久久久久|