OK論壇

 找回密碼
 註冊

【聊天室】

 關閉 [複製鏈接]
  • TA的每日心情
    開心
    2015-3-16 06:27 AM
  • 簽到天數: 421 天

    連續簽到: 1 天

    [LV.9]以壇為家II

    發表於 2013-3-28 10:06:04 | 顯示全部樓層
    傻庭兒 發表於 2013-3-28 09:59 AM
    好無聊啊,
    老師在講故事

    專心聽課比較實在
    除非你夠厲害XD

    回復 支持 反對

    使用道具 舉報

  • TA的每日心情

    2020-11-19 04:46 PM
  • 簽到天數: 2823 天

    連續簽到: 3 天

    [LV.Master]伴壇終老

    發表於 2013-3-28 10:06:37 | 顯示全部樓層
    睡醒                  
    回復 支持 反對

    使用道具 舉報

  • TA的每日心情

    2020-11-19 04:46 PM
  • 簽到天數: 2823 天

    連續簽到: 3 天

    [LV.Master]伴壇終老

    發表於 2013-3-28 10:36:18 | 顯示全部樓層
    原來RC語音也會伺服器超載..
    回復 支持 反對

    使用道具 舉報

  • TA的每日心情
    郁悶
    2023-2-25 10:45 PM
  • 簽到天數: 28 天

    連續簽到: 1 天

    [LV.4]偶爾看看III

    發表於 2013-3-28 11:05:19 | 顯示全部樓層
    f003002 發表於 2013-3-28 10:06 AM
    專心聽課比較實在
    除非你夠厲害XD

    哈哈哈,
    我很認真啊,下課可以看一下論壇
    回復 支持 反對

    使用道具 舉報

  • TA的每日心情
    無聊
    2024-4-18 08:16 PM
  • 簽到天數: 533 天

    連續簽到: 1 天

    [LV.9]以壇為家II

    發表於 2013-3-28 11:32:19 | 顯示全部樓層
    f003002 發表於 2013-3-28 09:59 AM
    要隔一星期才能申請
    本想申請變態區的XD

    等可以申請在來申請好了, 不知道能不能直接申請兩個~ {:soso_e102:}
    回復 支持 反對

    使用道具 舉報

  • TA的每日心情
    郁悶
    2023-2-25 10:45 PM
  • 簽到天數: 28 天

    連續簽到: 1 天

    [LV.4]偶爾看看III

    發表於 2013-3-28 11:46:15 | 顯示全部樓層
    -樂- 發表於 2013-3-28 10:36 AM
    原來RC語音也會伺服器超載..

    早安,
    繼續認真上課,哈哈哈
    回復 支持 反對

    使用道具 舉報

  • TA的每日心情

    2020-11-19 04:46 PM
  • 簽到天數: 2823 天

    連續簽到: 3 天

    [LV.Master]伴壇終老

    發表於 2013-3-28 12:38:59 | 顯示全部樓層
    fantasy83115 發表於 2013-3-28 11:32 AM
    等可以申請在來申請好了, 不知道能不能直接申請兩個~

    不能      
    回復 支持 反對

    使用道具 舉報

  • TA的每日心情

    2020-11-19 04:46 PM
  • 簽到天數: 2823 天

    連續簽到: 3 天

    [LV.Master]伴壇終老

    發表於 2013-3-28 12:39:14 | 顯示全部樓層
    傻庭兒 發表於 2013-3-28 11:46 AM
    早安,
    繼續認真上課,哈哈哈

    加油           
    回復 支持 反對

    使用道具 舉報

  • TA的每日心情

    2017-1-18 12:17 AM
  • 簽到天數: 512 天

    連續簽到: 1 天

    [LV.9]以壇為家II

    發表於 2013-3-28 12:53:50 | 顯示全部樓層
    f003002 發表於 2013-3-28 09:17 AM
    加油XD
    你可以PO出來啊,搞不好很多人都寫過,然後你就可以Ctrl+C+V
    交~作~業~
    1. 2013 spring PL project (OurScheme) - Project 1

    2. Due : 4/02(二) midnight (23:59)

    3.   // You are to implement something like the following
    4.                  
    5.   // 'exp' is a pointer that points to a linked list data structure;
    6.   // The linked list data structure results from reading in
    7.   // the user's input.

    8.   Print 'Welcome to OurScheme!'
    9.   Print '\n'
    10.   Print '> '

    11.   repeat
    12.   
    13.     ReadSExp(exp);
    14.     PrintSExp(exp); // You must "pretty print" this S-expression.
    15.     Print '> '
    16.    
    17.   until (OR (user entered '(exit)')
    18.             (END-OF-FILE encountered)
    19.         )

    20.   Print '\n'
    21.   Print 'Thanks for using OurScheme!' // Doesn't matter whether there is an
    22.                                       // '\n' at the end
    23. 2. Syntax of OurScheme

    24. terminal :
    25.   LEFT-PAREN       // '('
    26.   RIGHT-PAREN      // ')'
    27.   INT              // e.g., '123', '+123', '-123'
    28.   STRING           // "string's (example)." (strings do not extend across lines)
    29.   DOT              // '.'
    30.   FLOAT            // '123.567', '123.', '.567', '+123.4', '-.123'
    31.   NIL              // 'nil' or '#f', but not 'NIL' nor 'nIL'
    32.   T                // 't' or '#t', but not 'T' nor '#T'
    33.   QUOTE            // '
    34.   SYMBOL           // a consecutive sequence of printable characters that are
    35.                    // not numbers, and do not contain '(', ')', single-quote,
    36.                    // double-quote and white-spaces ;
    37.                    // Symbols are case-sensitive
    38.                    // (i.e., uppercase and lowercase are different);

    39. Note :

    40.   With the exception of strings, token are separated by the following "separators" :
    41.     (a) one or more white-spaces
    42.     (b) '('                               (note : '(' is a token by itself)
    43.     (c) ')'                               (note : ')' is a token by itself)
    44.     (d) the single-quote character (')    (note : it is a token by itself)
    45.     (e) the double-quote character (")    (note : it starts a STRING)

    46. Examples :

    47.   '3.25' is a FLOAT.
    48.   '3.25a' is a SYMBOL.
    49.   'a.b' is a SYMBOL.
    50.   '#f' is NIL
    51.   '#fa' (alternatively, 'a#f') is a SYMBOL.

    52. Note :

    53.   '.' can mean several things :
    54.     it is either part of a FLOAT or part of a SYMBOL or a DOT.
    55.    
    56.   It means a DOT only when it "stands alone".
    57.   
    58.   '#' can also mean two things :
    59.     it is either part of NIL (or T) or part of a SYMBOL.
    60.   
    61.   It is part of NIL (or T) only when it is '#t' or '#f' that "stand alone".
    62.   
    63. <S-exp> ::= <ATOM>
    64.             | LEFT-PAREN <S-exp> { <S-exp> } [ DOT <S-exp> ] RIGHT-PAREN
    65.             | QUOTE <S-exp>
    66.             
    67. <ATOM>  ::= SYMBOL | INT | FLOAT | STRING
    68.             | NIL | T | LEFT-PAREN RIGHT-PAREN

    69. Once the attempt to read in an S-expression fails, the line
    70. containing the error-char is ignored.  Start to read in an
    71. S-expression from the next input line.

    72. Note : a quoted S-expression '... is the same as (quote ...)

    73.    a. In C, the basic program building block is a statement.
    74.       In OurScheme, the basic program building block is
    75.       an S-expression (S-exp, for short).
    76.       
    77.    b. An S-exp is either an atom, a list, or a dotted pair.
    78.    
    79.    c. An atom is either an integer (e.g., 123), a float
    80.       (e.g., 12.34 or 12. or .34), a string (e.g., "Hi, there!"),
    81.       or a symbol (e.g., abc).
    82.       
    83.    d. Abc, abc, aBc, a-B!c?, !??, t, nil are examples of symbols
    84.    
    85.       // Blanks and line-returns ("white-space characters") are
    86.       // considered delimiters
    87.       
    88.       // Upper case and lower case are different, e.g., aB, AB, Ab,
    89.       // ab are all different symbols.
    90.       
    91.       // Each symbol may or may not be bound to an S-exp.
    92.       
    93.       // When I say that a symbol abc is bound to the S-exp
    94.       // (abc "Hi there" (5 3)),
    95.       // you could take what I mean to be that the "value" of abc
    96.       // is (abc "Hi there" (5 3)).
    97.       
    98.       // "Binding" (rather than "value") is a better way of saying
    99.       // what the situation really is.  
    100.       
    101.       // t, nil are two system-defined symbols
    102.       //   (t for "true" and nil for "false")
    103.       // They cannot be bound to any S-exp (i.e., they cannot be
    104.       // treated like user-defined symbols and cannot have values).
    105.       
    106.       // t is also written as #t, meaning "true"
    107.       // nil is also written as () or #f, meaning "false"
    108.       // In other word,
    109.       //   these two are the same : t   #t
    110.       //   these three are the same : nil   #f   ()
    111.       
    112.       // OurScheme understands both 't' and '#t', but it only prints '#t'
    113.       // OurScheme understands all these three : 'nil', '#f', '()',
    114.       //   but it only prints 'nil'.     
    115.       
    116.       // Side remark :
    117.       //   (True) Scheme uses #t, #f and ()
    118.       //   "Other Lisps" use t, nil and ()
    119.       
    120.    e. An 「S-exp sequence」 is of the form
    121.          S1 S2 S3 ... Sn
    122.       where each Si is an S-exp.
    123.       // e.g., (1) 1 (1 . 1)
    124.       // e.g., 1 2 (3 4 (5))
    125.       // Each of the above S-exp sequence contains three S-exp

    126.    f. A dotted pair is of the form
    127.         (SS1 . S2)
    128.       where S2 is an S-exp, whereas SS1 is an 「S-exp sequence」.
    129.       // Note that there is a dot between SS1 and S2,
    130.       //      with one or more spaces in between
    131.       // e.g., (1 . 2)
    132.       // e.g., (1  2  3  4  . 5)
    133.       // e.g., (1  2  3  4  . ())
    134.       // e.g., (1 . (2 . (3 . abc)))
    135.       // e.g., (1 2 3 . abc)
    136.       // e.g., ((1) (2 (3)) . (abc))
    137.       // e.g., ((1) (2 (3)) . (nil))
    138.       // e.g., ((1) (2 (3)) . nil)
    139.       
    140.    g. The following notations of dotted pairs are equivalent.
    141.       
    142.       (S1 S2 S3 S4 . S5)
    143.       (S1 . (S2 . (S3 . (S4 . S5))))
    144.       
    145.    h. Comment :
    146.       What we refer to as a "dotted pair" is different from what
    147.       other professionals refer to as a "dotted pair".
    148.       
    149.       What other professionals mean by a dotted pair is just
    150.       (S1 . S2), where S1 and S2 are S-exp.
    151.       
    152.    i. A list is of the form
    153.         (SS1)
    154.       where SS1 is an 「S-exp sequence」.
    155.       // Note : () is known as "the empty list"
    156.       // For historical reasons, () is defined to be the same
    157.       //   as nil or #f, meaning "false"
    158.       
    159.    j. A list (S1 S2 ... Sn) is actually a short-handed
    160.       notation for the following dotted pair
    161.         (S1 . (S2 . (...(Sn . nil)))...)))
    162.       In other words, a list is actually a special kind of
    163.       dotted pair.
    164.       
    165.       Another way of writing the list (S1 S2 ... Sn) is
    166.         (S1 S2 ... Sn . nil)
    167.         
    168.       // In other word, there are three (seven?) ways for writing
    169.       // the same list.
    170.       //   (S1 S2 S3 S4 S5)
    171.       //   (S1 . (S2 . (S3 . (S4 . (S5 . nil)))))
    172.       //   (S1 . (S2 . (S3 . (S4 . (S5 . #f )))))
    173.       //   (S1 . (S2 . (S3 . (S4 . (S5 . () )))))
    174.       //   (S1 S2 S3 S4 S5 . nil)
    175.       //   (S1 S2 S3 S4 S5 . #f)
    176.       //   (S1 S2 S3 S4 S5 . ())
    177.         
    178.    k. When the system prints out a dotted pair, it
    179.       always tries to print it in list-like format.
    180.       
    181.       For example, if the dotted pair is
    182.         (1 . (2 . (3 . (4 . 5))))
    183.       Then the system prints it as
    184.         (1 2 3 4 . 5)
    185.         
    186.       But if the dotted pair is
    187.         (1 . (2 . (3 . (4 . nil))))
    188.       The system does not print it as
    189.         (1 2 3 4 . nil)
    190.       Instead, the system prints it as
    191.         (1 2 3 4)
    192.    
    193.    l. Line comments
    194.    
    195.    A line comment begins with ';' until the end-of-line.
    196.    This ';' must be such that either it is the very first
    197.    character of the line or there is a separater preceding this ';'
    198.    on this line.
    199.    
    200.    (Therefore, for example, 'ab;b' is a symbol,
    201.     while 'ab ;b' is the symbol 'ab' followed by a
    202.     line comment that starts with ';b'.)
    203.         
    204. 3. Here are some examples of what your program should
    205.    do for project 1. (The following assumes that your program
    206.    runs interactively.)

    207. Welcome to OurScheme!

    208. > (1 . (2 . (3 . 4)))
    209. ( 1
    210.   2
    211.   3
    212.   .
    213.   4
    214. )

    215. > (1 . (2 . (3 . nil)))
    216. ( 1
    217.   2
    218.   3
    219. )

    220. > (1 . (2 . (3 . ())))
    221. ( 1
    222.   2
    223.   3
    224. )

    225. > (1 . (2 . (3 . #f)))
    226. ( 1
    227.   2
    228.   3
    229. )

    230. > a
    231. a

    232. > t
    233. #t

    234. > #t
    235. #t

    236. > nil
    237. nil

    238. > ()
    239. nil

    240. > #f
    241. nil

    242. > (t () . (1 2 3))
    243. ( #t
    244.   nil
    245.   1
    246.   2
    247.   3
    248. )

    249. > (t . nil . (1 2 3))
    250. ERROR (unexpected character) : line 1 column 10 character '.'

    251. > ((1 2 3) . (4 . (5 . nil)))
    252. ( ( 1
    253.     2
    254.     3
    255.   )
    256.   4
    257.   5
    258. )

    259. > ((1 2 3) . (4 . (5 . ())))
    260. ( ( 1
    261.     2
    262.     3
    263.   )
    264.   4
    265.   5
    266. )

    267. > (12.5       . (4 . 5))
    268. ( 12.500
    269.   4
    270.   .
    271.   5
    272. )

    273. > (10 12.())   ; same as : ( 10 12. () )
    274. ( 10
    275.   12.000
    276.   nil
    277. )

    278. > (10 ().125)   ; same as : ( 10 () .125 )
    279. ( 10
    280.   nil
    281.   0.125
    282. )

    283. > ( 1 2.5)
    284. ( 1
    285.   2.500
    286. )

    287. > ( 1 2.a)
    288. ( 1
    289.   2.a
    290. )

    291. > (1 2.25.5.a)
    292. ( 1
    293.   2.25.5.a
    294. )

    295. > (12 (    . 3))
    296. ERROR (unexpected character) : line 1 column 11 character ' '

    297. > "Hi"
    298. "Hi"

    299. > "(1 . 2   . 3)"
    300. "(1 . 2   . 3)"

    301. > (((1 . 2)
    302.     . ((3 4)
    303.        .
    304.        (5 . 6)
    305.       )
    306.    )
    307.    . (7 . 8)
    308.   )
    309. ( ( ( 1
    310.       .
    311.       2
    312.     )
    313.     ( 3
    314.       4
    315.     )
    316.     5
    317.     .
    318.     6
    319.   )
    320.   7
    321.   .
    322.   8
    323. )

    324. > ())
    325. nil

    326. > ERROR (unexpected character) : line 1 column 1 character ')'

    327. > (Hi there ! How are you ?)
    328. ( Hi
    329.   there
    330.   !
    331.   How
    332.   are
    333.   you
    334.   ?
    335. )

    336. > (Hi there! How are you?)
    337. ( Hi
    338.   there!
    339.   How
    340.   are
    341.   you?
    342. )

    343. > (Hi! (How about using . (Lisp (instead of . C?))))
    344. ( Hi!
    345.   ( How
    346.     about
    347.     using
    348.     Lisp
    349.     ( instead
    350.       of
    351.       .
    352.       C?
    353.     )
    354.   )
    355. )

    356. > (Hi there) (How are you)
    357. ( Hi
    358.   there
    359. )

    360. > ( How
    361.   are
    362.   you
    363. )
    364.          
    365. > (Hi
    366.            .
    367.            (there  .(     ; note that there may be no space between
    368.                           ; '.' and '('
    369.            How is it going?))
    370.            )
    371. ( Hi
    372.   there
    373.   How
    374.   is
    375.   it
    376.   going?
    377. )

    378. > ; Note : We have just introduced the use of comments.
    379.   ; ';' starts a comment until the end of line.
    380.   ; A comment is something that ReadSExp() should skip when
    381.   ; reading in an S-expression.
    382.   
    383. (1 2 3) )
    384. ( 1
    385.   2
    386.   3
    387. )

    388. > ERROR (unexpected character) : line 1 column 2 character ')'

    389. > (1 2
    390.    3) (4 5
    391. ( 1
    392.   2
    393.   3
    394. )

    395. >       6)
    396. ( 4
    397.   5
    398.   6
    399. )

    400. >        '(Hi
    401.            .
    402.            (there  .(     ; note that there may be no space between
    403.                           ; '.' and '('
    404.            How is it going?))
    405.            )
    406. ( quote
    407.   ( Hi
    408.     there
    409.     How
    410.     is
    411.     it
    412.     going?
    413.   )
    414. )

    415. >'(1 2 3) )
    416. ( quote
    417.   ( 1
    418.     2
    419.     3
    420.   )
    421. )

    422. > ERROR (unexpected character) : line 1 column 2 character ')'

    423. > '(1 2 3) .25
    424. ( quote
    425.   ( 1
    426.     2
    427.     3
    428.   )
    429. )

    430. > 0.250

    431. > (exit  ; as of now, your system only understands 'exit' ;
    432.       )  ; and the program terminates when it sees '(exit)'

    433. Thanks for using OurScheme!

    434. // =================== Q and A No. 1 =======================

    435. Question : '(1 2 3)的output應該是什麼?

    436. Answer :

    437. Project 1 :

    438. > '(1 2 3)
    439. ( quote
    440.   ( 1
    441.     2
    442.     3
    443.   )
    444. )


    445. Project 2 :

    446. > '(1 2 3)
    447. ( 1
    448.   2
    449.   3
    450. )

    451. 解釋:

    452. Project 1只讀進來(建出DS)、不evaluate就直接(把DS)印出去,
    453. 所以得 : (quote (1 2 3))。

    454. Project 2是讀進來(建出DS)、evaluate(此DS)、再把evaluate的result
    455. (依舊是個DS)印出去,所以得 : (1 2 3)。

    456. (將'(quote (1 2 3))'予以evaluate所得的結果是'(1 2 3)')

    457. // =================== Q and A No. 2 =======================

    458. ※ 引述《...》之銘言:

    459. > 請問老大~~

    460. > 1.當輸入'> .'時,會是ERROR嗎???
    461. >   若是是ERROR.msg:會是column: 1 or 2 ???

    462.    It is an error.  (Let us suppose that it is '> .$', where '$' is
    463.    LINE-ENTER char.)

    464.    column : 2   '.' is the very first user input char
    465.                 on this line.  (the space before it is system output)

    466.    Why column 2 and not column 1? Please see my answer to your second

    467.    question below. (The system detects an error when it sees the LINE-

    468.    ENTER char.)

    469. > 2.在測試數據中有輸入(12.5)(12(. 3))

    470. > 答案是:

    471. > > ( 12.500
    472. > )
    473. > > ERROR (unexpected character) : line 1 column 6 character ' '

    474. > 但是在OurScheme中

    475. > > (12 (    . 3))
    476. > ERROR (unexpected character) : line 1 column 10 character '.'

    477. > 之前的input是'.'錯,現在的input則是' '錯,為什麼呢???

    478. In the case of (the first one) '(12(. 3))', everything is still

    479. OK when the system (i.e., your system) "sees" '.'.  Why?  Because '.'

    480. may be followed by a digit such as '5'.  The system detects an error

    481. only when it sees that there is a space following '.'.  Therefore, the

    482. "error char" (the char that caused the error) is the space and not the '.'


    483. In the case of (the second one) '(12 (    . 3))', the error char should

    484. also be the space-char following that '.'   You just found an error in my

    485. Project 1 handout.  Thank you.  (And I have taken the liberty to

    486. correct this error in both OurSchemeProj1.txt and HowToWriteOurScheme.doc)


    487. > 3.請問abc"abc會印出什麼呢???

    488.   The first token is 'abc'. The second token is a string that starts

    489.   with : "abc

    490.   e.g., // for project 1

    491.   > abc"abc   "
    492.   abc

    493.   > "abc   "

    494. → yabuki 推:老大那abc'abc算是symbol嗎?還是會有其他結果?        03/09 22:27
    495. → hsia 推:the case of abc'abc similar to the above case,       03/10 08:57
    496. → hsia 推:because single-quote, double-quote R separators      03/10 08:58

    497. // =================== Q and A No. 3 =======================

    498. ※ 引述《...》之銘言:

    499. > 這問題困擾很久百思不得其解。

    500. >
    501. > 依題意應該是最後一個可以執行(或印出)的Token後將行號和欄位初始化
    502. > 範例如下

    503. > ()   )
    504. >  ^這玩意兒是最後的token,所以要印出在line 1錯

    505. > 問題來了:
    506. > "最後一個字串"\n
    507. > \n
    508. >   \n
    509. > "出錯點

    510. > 為什麼這裡印line 3?把最後一個字串token拿掉後應該如下
    511. > \n              1
    512. > \n                            2
    513. >   \n                          3
    514. > "出錯點                     第4行
    515. > ---------------

    516. > "最後一個字串"      \n 1
    517. > \n                            2
    518. >   \n                          3
    519. > "出錯點                       4

    520. > 加了空白為什麼也是line 3?

    521. 這沒什麼好百思不得其解的。 這是規劃時的思緒不夠細密。

    522. 的確,嚴格來講、按照規定、最後一個case的error應是第四行、而非第三行。

    523. 當初規劃時未考慮到「在legal input之後若還有(也只有)space怎麼算下一input的行數」

    524. 的問題。

    525. 不過,你就當這case是「general規定」的exception吧,意即:

    526.   在legal input之後(同一行)要出現「非space非tab字元」才把這一行
    527.   算作是下一input的第一行。  若legal input之後(同一行)只出現
    528. 「space或tab字元」,那這一行就不算作是下一input的第一行。

    529. ※ 引述《...》之銘言:
    530. > 請問一下PAL的proj2數據,當指令為(exit)時,output為
    531. >
    532. > Thanks for using OurScheme!

    533. > 為什麼不是
    534. > Thanks for using OurScheme!

    535. > 是不是要print "\nThanks for using OurScheme!"
    536. > 謝謝

    537. 答案是:

    538.   Project要求

    539.   > (     ;; user input, with an ENTER at the end
    540.           ;; user input, with an ENTER at the end
    541.     exit  ;; user input, with an ENTER at the end
    542.           ;; user input, with an ENTER at the end
    543.        )  ;; user input, with an ENTER at the end

    544.   Thanks for using OurScheme!;; system output


    複製代碼



    MY CODE
    1. // 小鮭魚 PL Project_01


    2. # include <stdio.h>
    3. # include <stdlib.h>
    4. # include <string.h>

    5. # define MAX_LISP_COUNT 15 // 最多可儲存幾組數據的樹 (包含ERROR樹)。
    6. # define STRING_LENGHT 150 // 一個 token (以字串儲存) 的最大長度。

    7. enum Syntax_type_1{ SYN_LEFT_PAREN = 1, SYN_RIGHT_PAREN = 2, SYN_INT = 3, SYN_FLOAT = 4, SYN_STRING = 5 } ;
    8. enum Syntax_type_2{ SYN_NIL = 6, SYN_T = 7, SYN_DOT = 8, SYN_QUOTE = 9, SYN_SYMBOL = 10 } ;

    9. static int uTestNum = 0 ;
    10. typedef char Str_[ STRING_LENGHT ] ; // 定義一個新指令 'Str_', 用途與 char XXX[STRING_LENGHT] 相同。

    11. // Data Struct : 樹中的每個節點的數據內容。
    12. struct LISP_DS {
    13.   Str_ str ;        // 存放 token
    14.   int synType ;     // 該token 的類型  
    15.   int dot ;         // 該點是否為 dot ( 0 : 未處理, 1 : 非dot, 2 : 為 dot )
    16.   LISP_DS * l_Ptr ; // 指向該點的左節點
    17.   LISP_DS * r_Ptr ; // 指向該點的右節點
    18. } ;
    19. typedef LISP_DS * LISP_Ptr ; // 定義一個新指令 'LISP_Ptr', 用途與 LISP_DS * XXX 相同。

    20. // ::::: 建樹類函數 Building Tree of Functions :::::
    21. void BuildLisp( int & contiScan, LISP_Ptr & lisp, Str_ & str, char & nextChar, int countLR ) ;
    22. bool Tree_CreateNode( LISP_Ptr & walker ) ;
    23. bool Tree_EndNode( LISP_Ptr & walker ) ;
    24. bool Tree_SetToken( LISP_Ptr & walker, Str_ str, int syntaxType ) ;
    25. bool Tree_SetDot( LISP_Ptr & walker, int dotType ) ;

    26. // ::::: 印樹類函數 Printing Tree of Functions :::::
    27. void PrintLisp( LISP_Ptr walker, char from_LR, int space ) ;
    28. bool StopPrint( LISP_Ptr lisp ) ;
    29. bool IsSoloToken( LISP_Ptr lisp ) ;

    30. // ::::: 切字元類函數 Get Token of Functions :::::
    31. int GetToken( Str_ & str, char & nextChar ) ;
    32. bool Check_Separation( char ch, char & nextChar ) ;
    33. int Syntax_Number( Str_ & str, char & nextChar, char & ch, int & successGet, int & stillScan ) ;
    34. int Syntax_String( Str_ & str, char & nextChar, char & ch, int & successGet, int & stillScan ) ;
    35. int Syntax_Dot( Str_ & str, char & nextChar, char & ch, int & successGet, int & stillScan ) ;
    36. int Syntax_Symbol( Str_ & str, char & nextChar, char & ch, int & successGet, int & stillScan ) ;
    37. void TokenReset( Str_ str, int syntaxType ) ;

    38. // ::::: 工具類函數 Tools Function :::::
    39. void CleanString( Str_ & str ) ;
    40. void SkipLine() ;
    41. void PrintWhiteSpace( int space ) ;


    42. // main - 好戲上場 :)
    43. int main() {
    44.   scanf( "%d ", &uTestNum ) ;
    45.   printf( "Welcome to OurScheme!\n" ) ;

    46.   // 前置宣告。
    47.   Str_ str = "\0" ;
    48.   char nextChar = '\0' ;
    49.   LISP_Ptr lisp_tree[ MAX_LISP_COUNT ] ; // 建立出 MAX_LISP_COUNT 個樹空間的陣列。
    50.   int totalBuildCount = 0 ;             // 總共當前已建立的樹之數量。
    51.   
    52.   // 建立 tree, 同時於該 function 進行資料 scan 的動作。
    53.   // 此處的 contiScan 變數為 scanf 時, 若 EOF 則回傳 -1。
    54.   for ( int i = 0, contiScan = 1 ; i < MAX_LISP_COUNT && contiScan != -1 ; i ++ ) {
    55.     lisp_tree[i] = new LISP_DS(), lisp_tree[i]->l_Ptr = lisp_tree[i]->r_Ptr = NULL ;
    56.     BuildLisp( contiScan, lisp_tree[i], str, nextChar, 0 ) ;
    57.     totalBuildCount ++ ;
    58.   } // for
    59.   
    60.   // 印出 tree, 須注意不滿 10 組樹將會顯示 Error message, 遇到 (exit), 也會立刻終止印出。
    61.   bool stopPrint = StopPrint( lisp_tree[0] ) ; // 先判斷第一組樹是否為 (exit)
    62.   for ( int i = 0 ; i < totalBuildCount && ! stopPrint ; i ++ ) {
    63.     if ( ! IsSoloToken( lisp_tree[i] ) )
    64.       printf( "\n> " ), PrintLisp( lisp_tree[i], 'S', 0 ) ;
    65.     else
    66.       if ( lisp_tree[i] != NULL )
    67.         if ( lisp_tree[i]->l_Ptr != NULL )
    68.           printf( "\n> %s\n", lisp_tree[i]->l_Ptr->str ) ;
    69.     stopPrint = StopPrint( lisp_tree[i+1] ) ; // 預先判斷下一組樹是否為 (exit)
    70.   } // for
    71.   
    72.   if ( totalBuildCount < 10 )
    73.     printf( "ERROR : END-OF-FILE encountered when there should be more input\n\n" ) ;
    74.   printf( "Thanks for using OurScheme!" ) ;
    75.   
    76.   return 0 ;
    77. } // main()


    78. // ::::: 建樹類函數 Building Tree of Functions :::::

    79. // BuildLisp : 建立一個完整的樹。
    80. void BuildLisp( int & synType, LISP_Ptr & lisp, Str_ & str, char & nextChar, int countLR ) {
    81.   // 每次會先取得一個 token, 若 GetToken 回傳 -1 表示取得失敗 (可能為white space字元),
    82.   // 成功取得字元後進行建樹動作, 以下為建樹步驟 :
    83.   // 1. 若為上括號 - 新開一組節點空間 ; countLR + 1。
    84.   // 2. 若為下括號 - 將最先遇到可存放 token 的節點存放 nil 的 token ; countLR - 1。
    85.   // 3. 若為'.'DOT - 表示接下來的 token 與 token 連接有 DOT。
    86.   // 4. 若為一般 token - 將最先遇到可存放 token 的節點使之存放 (存放之前先將其呈現方式轉換, 如小數點末三位...etc)。
    87.   // 5. 當 countLR 為 0 時, 此組數據結束, BuildLisp 亦結束, 將此完成的樹回傳給 main。
    88.   CleanString( str ) ;                    // 防止 error, 率先將字串清除。
    89.   synType = GetToken( str, nextChar ) ;   // nextChar 為被打回包票的字元, 他必須自成一格。
    90.   if ( synType == -1 )                    // synType 若讀到 EOF 則回傳 -1, 則結束繼續讀入建樹動作。
    91.     return ;
    92.   
    93.   if ( strcmp( str, "" ) != 0 ) {          // token 不為 null 才可進行判斷。
    94.     if ( strcmp( str, "(" ) == 0 ) {         // token 為 '(' 上括號。  
    95.       countLR ++ ;
    96.       if ( countLR > 1 ) // 這裡比較特殊, 第一次遇到的括號不需要新開節點 (交給下一次的 token 吧!)。
    97.         Tree_CreateNode( lisp ) ;
    98.     } // if
    99.     else if ( strcmp( str, ")" ) == 0 ) {    // token 為 ')' 下括號。  
    100.       countLR -- ;
    101.       Tree_EndNode( lisp ) ;
    102.     } // else if
    103.     else if ( strcmp( str, "." ) == 0 ) {    // token 為 '.' DOT。  
    104.       
    105.     } // else if
    106.     else {                                  // 一般 token 放入樹中。
    107.       // if ( synType == SYN_FLOAT )           // 浮點數呈現方式轉換。
    108.       Tree_CreateNode( lisp ) ;
    109.       Tree_SetToken( lisp, str, synType );
    110.     } // else
    111.    
    112.     if ( countLR == 0 )                     // 左右括號的平均檢測, 左括號+1, 右括號-1, 為 0則完畢該樹建立。
    113.       return ;
    114.   } // if
    115.   
    116.   BuildLisp( synType, lisp, str, nextChar, countLR ) ;
    117. } // BuildLisp()

    118. // Tree_CreateNode : 節點新建, 用於 '(' 出現 與 新 token 放入前的前置作業。
    119. bool Tree_CreateNode( LISP_Ptr & walker ) {
    120.   // 使用遞迴去旅行整棵樹, 將第一次遇到的 "該節點無 token 且雙向節點皆指向 NULL" 者新開節點並結束 function。
    121.   if ( strcmp( walker->str, "" ) == 0 && walker->l_Ptr == NULL && walker->r_Ptr == NULL ) {
    122.     walker->l_Ptr = new LISP_DS(), walker->r_Ptr = new LISP_DS() ;
    123.     walker->l_Ptr->l_Ptr = walker->l_Ptr->r_Ptr = NULL ;
    124.     walker->r_Ptr->l_Ptr = walker->r_Ptr->r_Ptr = NULL ;
    125.     return true ;
    126.   } // if
    127.   else {
    128.     if ( walker->l_Ptr != NULL )
    129.       if ( Tree_CreateNode( walker->l_Ptr ) )
    130.         return true ;
    131.     if ( walker->r_Ptr != NULL )
    132.       if ( Tree_CreateNode( walker->r_Ptr ) )
    133.         return true ;
    134.     return false ;
    135.   } // else
    136. } // Tree_CreateNode()

    137. // Tree_EndNode : 節點完畢, 用於 ')'出現。
    138. // 使用遞迴去旅行整棵樹, 將第一次遇到的 "該節點無 token 且雙向節點皆指向 NULL" 存入 "nil" token 並結束 function。
    139. bool Tree_EndNode( LISP_Ptr & walker ) {
    140.   if ( strcmp( walker->str, "" ) == 0 && walker->l_Ptr == NULL && walker->r_Ptr == NULL ) {
    141.     strcpy( walker->str, "nil" ) ;
    142.     return true ;
    143.   } // if
    144.   else {
    145.     if ( walker->l_Ptr != NULL )
    146.       if ( Tree_EndNode( walker->l_Ptr ) )
    147.         return true ;
    148.     if ( walker->r_Ptr != NULL )
    149.       if ( Tree_EndNode( walker->r_Ptr ) )
    150.         return true ;
    151.     return false ;
    152.   } // else
    153. } // Tree_EndNode()

    154. // Tree_SetToken : 放置 token 於節點當中。
    155. // 使用遞迴去旅行整棵樹, 將第一次遇到的 "該節點無 token 且雙向節點皆指向 NULL" 存入 token 並結束 function。
    156. bool Tree_SetToken( LISP_Ptr & walker, Str_ str, int syntaxType ) {
    157.   if ( strcmp( walker->str, "" ) == 0 && walker->l_Ptr == NULL && walker->r_Ptr == NULL ) {
    158.     if ( syntaxType == SYN_INT || syntaxType == SYN_FLOAT || syntaxType == SYN_NIL || syntaxType == SYN_T )
    159.       TokenReset( str, syntaxType ) ; // 若為特殊 token, 他必須轉換後在儲存起來。
    160.     strcpy( walker->str, str ) ;
    161.     walker->synType = syntaxType ;
    162.     return true ;
    163.   } // if
    164.   else {
    165.     if ( walker->l_Ptr != NULL )
    166.       if ( Tree_SetToken( walker->l_Ptr, str, syntaxType ) )
    167.         return true ;
    168.     if ( walker->r_Ptr != NULL )
    169.       if ( Tree_SetToken( walker->r_Ptr, str, syntaxType ) )
    170.         return true ;
    171.     return false ;
    172.   } // else
    173. } // Tree_SetToken()
    174.    
    175. // Tree_SetDot : 放置 dot 於節點當中 (1 : 非DOT, 2 : 為DOT)。
    176. bool Tree_SetDot( LISP_Ptr & walker, int dotType ) {
    177.   

    178. } // Tree_SetDot()

    179. // ::::: 印樹類函數 Printing Tree of Functions :::::

    180. // PrintLisp : 印出該樹。
    181. bool gSpace_Skip = true ;
    182. void PrintLisp( LISP_Ptr walker, char from_LR, int space ) {
    183.   // from_LR 的用義為, 告訴遞迴的子函數, 他是左節點還是右節點 (S-Start 首節點, L-Left 左節點, R-Right 右節點)。
    184.   // space 的用意是, 當前行數需要印出幾組空白作縮排。
    185.   if ( walker->l_Ptr != NULL && walker->r_Ptr != NULL )       // 如果說 該節點的左節點與右節點的 token 皆為 "nil", 就別印了。
    186.     if ( ( strcmp( walker->l_Ptr->str, "nil" ) == 0 && strcmp( walker->r_Ptr->str, "nil" ) == 0 ) ||
    187.          ( strcmp( walker->l_Ptr->str, "nil" ) == 0 && strcmp( walker->r_Ptr->str, "nil" ) == 0 ) )
    188.       return ;
    189.   
    190.   // 以下是印上括弧。
    191.   if ( ( from_LR == 'S' || from_LR == 'L' ) && strcmp( walker->str, "" ) == 0 ) {
    192.     if ( ! gSpace_Skip )
    193.       PrintWhiteSpace( space ) ;
    194.     space ++, gSpace_Skip = true ;
    195.     printf( "( " ) ;
    196.   } // if

    197.   // 以下是印一般 token。
    198.   if ( strcmp( walker->str, "nil" ) == 0 && from_LR == 'R' )   // 右節點的 nil 統一不印出來, 他只是象徵該 dotted pair 結束。
    199.     ;
    200.   else if ( strcmp( walker->str, "" ) != 0 ) {                 // 一般 token 皆須要列印出來。
    201.     if ( ! gSpace_Skip )
    202.       PrintWhiteSpace( space ) ;
    203.     gSpace_Skip = false ;
    204.     printf( "%s\n", walker->str ) ;
    205.   } // else if
    206.    
    207.   // 以下是印下括弧。
    208.   if ( strcmp( walker->str, "nil" ) == 0 && from_LR == 'R' ) {
    209.     space -- ;
    210.     PrintWhiteSpace( space ) ;
    211.     printf( ")\n" ) ;
    212.   } // if
    213.   
    214.   if ( walker->l_Ptr != NULL )
    215.     PrintLisp( walker->l_Ptr, 'L', space ) ;
    216.   if ( walker->r_Ptr != NULL )
    217.     PrintLisp( walker->r_Ptr, 'R', space ) ;   
    218. } // PrintLisp()

    219. // StopPrint : 何時停止? 遇到 (exit) 的時候ㄛ !
    220. // 內部儲存空間的樹必須為以下形態 :
    221. //       口                        |         口      單一 token 無括號, 這個是不會停止的
    222. //     ↙ ↘                      |       ↙ ↘
    223. //   exit   nil     此為 (exit)    |     exit    口  此為 exit
    224. bool StopPrint( LISP_Ptr lisp ) {
    225.   if ( lisp != NULL )
    226.     if ( lisp->l_Ptr != NULL && lisp->r_Ptr != NULL )
    227.       if ( strcmp( lisp->l_Ptr->str, "exit" ) == 0 && strcmp( lisp->r_Ptr->str, "nil" ) == 0 )
    228.         return true ;
    229.   
    230.   return false ;
    231. } // StopPrint()

    232. // isSoloToken : 是否為單一 token, 且無括號 ?
    233. bool IsSoloToken( LISP_Ptr lisp ) {
    234.   if ( lisp != NULL )
    235.     if ( lisp->l_Ptr != NULL && lisp->r_Ptr != NULL )
    236.       if ( strcmp( lisp->l_Ptr->str, "" ) != 0 && strcmp( lisp->r_Ptr->str, "" ) == 0 )
    237.         if ( lisp->r_Ptr->l_Ptr == NULL && lisp->r_Ptr->r_Ptr == NULL )
    238.           return true ;
    239.   return false ;
    240. } // IsSoloToken()


    241. // ::::: 切字元類函數 Get Token of Functions :::::

    242. // GetToken : 切切切字元。
    243. int GetToken( Str_ & str, char & nextChar ) {
    244.   char ch = '\0' ;      // 宣告 : 讀到的字元。
    245.   int successGet = 1 ;  // 宣告 : 是否成功讀到字元, 字元讀取失敗(EOF回傳 -1)。
    246.   int stillScan = 1 ;   // 宣告 : 是否要繼續讀取自元放入 token 中? (中斷原因遇到分離字元, 回傳-1)。
    247.   int synType = 0 ;     // 宣告 : 該 token 的類型, 共 10 類, 見置頂 enum。
    248.   
    249.   while ( successGet != -1 && stillScan != -1 ) {
    250.     // 若 nextChar (此變數用途為, 被打回包票須自成一格的字元) 為 null,
    251.     // 代表上一筆是正常 token, 未跟其他 token 連結在一起.
    252.     // 1. nextChar 為 null 時, 再讀一個字元.
    253.     // 2. nextChar 非 null 時, 不需再讀一個字元, 用 nextChar 去再切下一個 token.
    254.     if ( nextChar == '\0' )        
    255.       successGet = scanf( "%c", & ch ) ;
    256.     else
    257.       ch = nextChar, nextChar = '\0' ;
    258.    
    259.     // white space類 : 若讀到空格或換行, 則此 token 切割完畢。
    260.     if ( ch == ' ' || ch == '\n' )
    261.       stillScan = -1 ;
    262.     // 括弧類 : (回傳1)左括號 ; (回傳2)右括號。
    263.     else if ( ch == '(' || ch == ')' ) {
    264.       if ( ch == '(' )
    265.         strcpy( str, "(" ), synType = SYN_LEFT_PAREN, stillScan = -1 ;
    266.       else if ( ch == ')' )
    267.         strcpy( str, ")" ), synType = SYN_RIGHT_PAREN, stillScan = -1 ;
    268.     } // else if
    269.     // 數字類 : (回傳3)整數 +123, -321 ; (回傳4)浮點數 -1.23, 3.21 ; (回傳10)Symbol 1.e, 1.5.8。
    270.     // ASCII碼介於 0~9 且包含 +, - 兩符號。
    271.     else if ( ( ch >= '0' && ch <= '9' ) || ch == '+' || ch == '-' ) {
    272.       synType = Syntax_Number( str, nextChar, ch, successGet, stillScan ) ;
    273.     }  // else if
    274.     // 字串類 : (回傳5)由雙引號開頭, 雙引號結尾, 若該字串不成立則回傳-1。
    275.     else if ( ch == '"' ) {
    276.       synType = Syntax_String( str, nextChar, ch, successGet, stillScan ) ;
    277.     } // else if
    278.     // DOT類 : (回傳4)浮點數 .0123 ; (回傳8)純DOT . ; (回傳10)Symbol .abc。
    279.     else if ( ch == '.' ) {
    280.       synType = Syntax_Dot( str, nextChar, ch, successGet, stillScan ) ;
    281.     } // else if
    282.     // 註解類 : 直到讀進 '\n'換行 或 EOF 才回傳。
    283.     else if ( ch == ';' ) {
    284.       SkipLine() ;
    285.     } // else if
    286.     // quote類 : (回傳9)單引號。
    287.     else if ( ch == '\'' ) {
    288.       strcpy( str, "\'" ), synType = SYN_QUOTE, stillScan = -1 ;
    289.     } // else if
    290.     // Symbol類 : (回傳6)nil, #f ; (回傳7)t, #t ; (回傳10)Symbol asd15a 15a.d.1。
    291.     else {
    292.       synType = Syntax_Symbol( str, nextChar, ch, successGet, stillScan ) ;
    293.     } // else   
    294.   } // while
    295.    
    296.   if ( successGet == -1 ) // 讀到了 EOF, 結束所有建樹動作。
    297.     return -1 ;
    298.   
    299.   return synType ;        // 回傳該 token 類型。
    300. } // GetToken()

    301. // Check_Separation : 再各類的細分函數中, 若讀到以下字元將強制結束並將該字元設為 nextChar。
    302. // 分離字元有 ' '(空白), '\n'(換行), '"'(雙引號), '''(單引號), '('(上引號), ')'(下引號), ';'(分號)。
    303. bool Check_Separation( char ch, char & nextChar ) {
    304.   if ( ch == ' ' || ch == '\n' || ch == '"' || ch == '\'' || ch == '(' || ch == ')' || ch == ';' ) {
    305.     nextChar = ch ;
    306.     return true ; // 是分離字元的其中一員, nextChar 改變。
    307.   } // if
    308.   
    309.   return false ;  // 並非分離字元的其中一員。
    310. } // Check_Separation()

    311. // Syntax_Number : 數字類細分 - (回傳3)整數 +123, -321 ; (回傳4)浮點數 -1.23, +.21 ; (回傳10)Symbol 1.e, 1.5.8。
    312. int Syntax_Number( Str_ & str, char & nextChar, char & ch, int & successGet, int & stillScan ) {
    313.   str[ strlen( str ) ] = ch ;                   // 先將該 token 第一個字元放入。
    314.   // 以下開始將為組合 token。
    315.   while ( successGet != -1 && stillScan != -1 ) {
    316.     successGet = scanf( "%c", & ch ) ;           // 讀進下一個字元並將他傳去檢查是否為分離字元。
    317.     if ( Check_Separation( ch, nextChar ) )     // 若是有分離字元存在, 就取消繼續組合 token。
    318.       stillScan = -1 ;
    319.     else
    320.       str[ strlen( str ) ] = ch ;
    321.   } // while
    322.          
    323.   // 以下開始將為 token 分類。
    324.   int countPoint = 0 ;       // 小數點計算
    325.   for ( int i = 0 ; i < strlen( str ) ; i ++ )
    326.     if ( str[i] == '.' )     // 若為 '.', 小數點總數上升。
    327.       countPoint ++ ;
    328.   // 第壹關 : 整數判斷(第一個字元允許 +,- ; 其餘字元只允許 0~9)。
    329.   bool isInterger = true ;
    330.   if ( countPoint == 0 ) {
    331.     if ( str[0] == '+' || str[0] == '-' || ( str[0] >= '0' && str[0] <= '9' ) ) {
    332.       for ( int i = 1 ; i < strlen( str ) ; i ++ ) // 若出現的字元出現非 0~9, 就不是整數 (從index = 1 開始判斷)
    333.         if ( ! ( str[i] >= '0' && str[i] <= '9' ) )
    334.           isInterger = false ;
    335.     } // if
    336.     else
    337.       isInterger = false ;
    338.     if ( isInterger )
    339.       return SYN_INT ;
    340.   } // if
    341.   // 第貳關 : 浮點數判斷(只可出現一次小數點 ; 第一個字元允許 +,- ; 其餘字元只允許 0~9)。
    342.   // 請問 .135 要考慮嗎 ? 不, 這種情況被歸類再 Syntax_Dot 中作處理, 但這裡有 +.123 要留意。)。
    343.   bool isFloat = true ;
    344.   if ( countPoint == 1 ) {
    345.     if ( str[0] == '+' || str[0] == '-' || ( str[0] >= '0' && str[0] <= '9' ) ) {
    346.       for ( int i = 1 ; i < strlen( str ) ; i ++ ) // 若出現的字元出現非 0~9或 ., 就不是浮點數 (從index = 1 開始判斷)
    347.         if ( ! ( str[i] >= '0' && str[i] <= '9' ) && str[i] != '.' )
    348.           isFloat = false ;
    349.     } // if
    350.     else
    351.       isFloat = false ;
    352.     if ( isFloat )
    353.       return SYN_FLOAT ;
    354.   } // if
    355.   // 第&#21442;關 : 講了這麼多, 你就是 Symbol 啊 !
    356.   return SYN_SYMBOL ;
    357. } // Syntax_Number()

    358. // Syntax_String : 字串類細分 - (回傳5)由雙引號開頭, 雙引號結尾, 若該字串不成立則回傳-1。
    359. int Syntax_String( Str_ & str, char & nextChar, char & ch, int & successGet, int & stillScan ) {
    360.   str[ strlen( str ) ] = ch ;
    361.   // 以下開始將為組合 token。
    362.   while ( successGet != -1 && stillScan != -1 ) {
    363.     successGet = scanf( "%c", & ch ) ;  // 讀進下一個字元並放入 (若是 '\n'換行 , 則 ERROR)。
    364.     str[ strlen( str ) ] = ch ;
    365.     if ( ch == '"' )                   // 讀到雙引號結束, 此 token 完畢
    366.       stillScan = -1 ;
    367.     else if ( ch == '\n' ) {            // 讀到換行字元, 刪除此 token, 並且回報錯誤。
    368.       stillScan = -1, CleanString( str ) ;
    369.       return 0 ;
    370.     } // else if
    371.   } // while
    372.   
    373.   return SYN_STRING ;
    374. } // Syntax_String()

    375. // Syntax_Dot : DOT類細分 - (回傳4)浮點數 .0123 ; (回傳8)純DOT . ; (回傳10)Symbol .abc。
    376. int Syntax_Dot( Str_ & str, char & nextChar, char & ch, int & successGet, int & stillScan ) {
    377.   str[ strlen( str ) ] = ch ;                   // 先將該 token 第一個字元放入。
    378.   // 以下開始將為組合 token。
    379.   while ( successGet != -1 && stillScan != -1 ) {
    380.     successGet = scanf( "%c", & ch ) ;          // 讀進下一個字元並將他傳去檢查是否為分離字元。
    381.     if ( Check_Separation( ch, nextChar ) )     // 若是有分離字元存在, 就取消繼續組合 token。
    382.       stillScan = -1 ;
    383.     else
    384.       str[ strlen( str ) ] = ch ;
    385.   } // while
    386.          
    387.   // 以下開始將為 token 分類。
    388.   int countPoint = 0 ;       // 小數點計算
    389.   for ( int i = 0 ; i < strlen( str ) ; i ++ )
    390.     if ( str[i] == '.' )     // 若為 '.', 小數點總數上升。
    391.       countPoint ++ ;
    392.   // 第壹關 : 浮點數判斷(只可出現一次小數點 ; 其餘字元只允許 0~9)。
    393.   bool isFloat = true ;
    394.   if ( countPoint == 1 )  {
    395.     for ( int i = 1 ; i < strlen( str ) ; i ++ ) // 若出現的字元出現非 0~9或 ., 就不是浮點數 (從index = 0 開始判斷)
    396.       if ( ! ( str[i] >= '0' && str[i] <= '9' ) )
    397.         isFloat = false ;
    398.     if ( isFloat )
    399.       return SYN_FLOAT ;
    400.   } // if
    401.   // 第貳關 : DOT判斷, 就只是一個 DOT 字串。
    402.   if ( strcmp( str, "." ) == 0 )
    403.     return SYN_DOT ;
    404.   // 第&#21442;關 : 講了這麼多, 你就是 Symbol 啊 !
    405.   return SYN_SYMBOL ;
    406. } // Syntax_Dot()

    407. // Syntax_Symbol : Symbol類細分 - (回傳3)整數 +123, -321 ; (回傳4)浮點數 -1.23, 3.21 ; (回傳10)Symbol 1.e, 1.5.8。
    408. int Syntax_Symbol( Str_ & str, char & nextChar, char & ch, int & successGet, int & stillScan ) {
    409.   str[ strlen( str ) ] = ch ;                   // 先將該 token 第一個字元放入。
    410.   // 以下開始將為組合 token。
    411.   while ( successGet != -1 && stillScan != -1 ) {
    412.     successGet = scanf( "%c", & ch ) ;          // 讀進下一個字元並將他傳去檢查是否為分離字元。
    413.     if ( Check_Separation( ch, nextChar ) )     // 若是有分離字元存在, 就取消繼續組合 token。
    414.       stillScan = -1 ;
    415.     else
    416.       str[ strlen( str ) ] = ch ;
    417.   } // while
    418.   
    419.   // 以下開始將為 token 分類。
    420.   int countPoint = 0 ;       // 小數點計算
    421.   for ( int i = 0 ; i < strlen( str ) ; i ++ )
    422.     if ( str[i] == '.' )     // 若為 '.', 小數點總數上升。
    423.       countPoint ++ ;
    424.   // 第壹關 : 整數判斷(第一個字元允許 +,- ; 其餘字元只允許 0~9)。
    425.   bool isInterger = true ;
    426.   if ( countPoint == 0 ) {
    427.     if ( str[0] == '+' || str[0] == '-' || ( str[0] >= '0' && str[0] <= '9' ) ) {
    428.       for ( int i = 1 ; i < strlen( str ) ; i ++ ) // 若出現的字元出現非 0~9, 就不是整數 (從index = 1 開始判斷)
    429.         if ( ! ( str[i] >= '0' && str[i] <= '9' ) )
    430.           isInterger = false ;
    431.     } // if
    432.     else
    433.       isInterger = false ;
    434.     if ( isInterger )
    435.       return SYN_INT ;
    436.   } // if
    437.   // 第貳關 : 浮點數判斷(只可出現一次小數點 ; 第一個字元允許 +,- ; 其餘字元只允許 0~9)。
    438.   // 請問 .135 要考慮嗎 ? 不, 這種情況被歸類再 Syntax_Dot 中作處理, 但這裡有 +.123 要留意。)。
    439.   bool isFloat = true ;
    440.   if ( countPoint == 1 ) {
    441.     if ( str[0] == '+' || str[0] == '-' || ( str[0] >= '0' && str[0] <= '9' ) ) {
    442.       for ( int i = 1 ; i < strlen( str ) ; i ++ ) // 若出現的字元出現非 0~9或 ., 就不是浮點數 (從index = 1 開始判斷)
    443.         if ( ! ( str[i] >= '0' && str[i] <= '9' ) && str[i] != '.' )
    444.           isFloat = false ; // isFloat = false ;
    445.     } // if
    446.     else
    447.       isFloat = false ;
    448.     if ( isFloat )
    449.       return SYN_FLOAT ;
    450.   } // if
    451.   // 第&#21442;關 : NIL 判斷。
    452.   if ( strcmp( str, "nil" ) == 0 || strcmp( str, "#f" ) == 0 )
    453.     return SYN_NIL ;
    454.   // 第肆關 : #t 判斷。
    455.   if ( strcmp( str, "t" ) == 0 || strcmp( str, "#t" ) == 0 )
    456.     return SYN_T ;
    457.   // 第伍關 : 單引號判斷。
    458.   if ( strcmp( str, "\'" ) == 0 )
    459.     return SYN_QUOTE ;
    460.   // 第陸關 : 講了這麼多, 你就是 Symbol 啊 !
    461.   return SYN_SYMBOL ;
    462. } // Syntax_Symbol()

    463. // TokenReset : 這個 token 特殊類別需額外修改 (包含 SYN_INT、SYN_FLOAT、SYN_NIL、SYN_T)。
    464. void TokenReset( Str_ str, int syntaxType ) {
    465.   if ( syntaxType == SYN_INT ) {
    466.     int tempInt = atoi( str ) ;
    467.     sprintf( str, "%d", tempInt ) ;
    468.   } // if
    469.   else if ( syntaxType == SYN_FLOAT ) {
    470.     float tempFloat = atof( str ) ;
    471.     sprintf( str, "%.3f", tempFloat ) ;
    472.   } // else if
    473.   else if ( syntaxType == SYN_NIL ) {
    474.     strcpy( str, "nil" ) ;
    475.   } // else if
    476.   else if ( syntaxType == SYN_T ) {
    477.     strcpy( str, "#t" ) ;
    478.   } // else if
    479. } // TokenReset()


    480. // ::::: 工具類函數 Tools of Functions :::::

    481. // CleanString : 字串內容完全清除。
    482. void CleanString( Str_ & str ) {
    483.   for ( int i = 0 ; i < STRING_LENGHT ; i ++ )
    484.     str[i] = '\0' ;
    485. } // CleanString()

    486. // SkipLine : 遇到註解時的跳行字元 (直到 '\n' or EOF 時 return)。
    487. void SkipLine() {
    488.   char ch = '\0' ;
    489.   // out 為判斷 EOF 的依據。
    490.   for ( int out = scanf( "%c", & ch ) ; ch != '\n' && out != -1 ; out = scanf( "%c", & ch ) )
    491.     if ( ch != '\n' ) ;
    492. } // SkipLine()

    493. // PrintWhiteSpace : 印出縮排用的空白。
    494. void PrintWhiteSpace( int space ) {
    495.   for ( int i = 0 ; i < space ; i ++ )
    496.     printf( "  " ) ;
    497. } // PrintWhiteSpace()
    複製代碼
    回復 支持 反對

    使用道具 舉報

  • TA的每日心情
    無聊
    2024-4-18 08:16 PM
  • 簽到天數: 533 天

    連續簽到: 1 天

    [LV.9]以壇為家II

    發表於 2013-3-28 13:15:00 | 顯示全部樓層
    本帖最後由 fantasy83115 於 2013-3-28 01:16 PM 編輯
    grass0916 發表於 2013-3-28 12:53 PM
    MY CODE

    這算幾樓.. 好長一篇
    怎感覺頗像java / 你的code 跟c++卻好像 {:soso_e107:}
    回復 支持 反對

    使用道具 舉報

  • TA的每日心情
    郁悶
    2023-2-25 10:45 PM
  • 簽到天數: 28 天

    連續簽到: 1 天

    [LV.4]偶爾看看III

    發表於 2013-3-28 13:30:36 | 顯示全部樓層
    要500了欸,
    還沒吃午餐,好餓
    回復 支持 反對

    使用道具 舉報

  • TA的每日心情
    無聊
    2024-4-18 08:16 PM
  • 簽到天數: 533 天

    連續簽到: 1 天

    [LV.9]以壇為家II

    發表於 2013-3-28 13:43:44 | 顯示全部樓層
    誰是下一個受害者 (500F).
    回復 支持 反對

    使用道具 舉報

  • TA的每日心情
    無聊
    2024-4-18 08:16 PM
  • 簽到天數: 533 天

    連續簽到: 1 天

    [LV.9]以壇為家II

    發表於 2013-3-28 13:50:29 | 顯示全部樓層
    綠色的影子會不會很奇怪阿..?

    回復 支持 反對

    使用道具 舉報

  • TA的每日心情
    開心
    2019-8-18 04:57 PM
  • 簽到天數: 2148 天

    連續簽到: 1 天

    [LV.Master]伴壇終老

    發表於 2013-3-28 13:51:47 | 顯示全部樓層
    grass0916 發表於 2013-3-28 12:53 PM
    MY CODE

    善用http://pastebin.com/
    回復 支持 反對

    使用道具 舉報

  • TA的每日心情
    開心
    2019-8-18 04:57 PM
  • 簽到天數: 2148 天

    連續簽到: 1 天

    [LV.Master]伴壇終老

    發表於 2013-3-28 13:55:58 | 顯示全部樓層
    同一篇文章

    有人一看就懂

    有人一直說不懂

    很有趣吧
    回復 支持 反對

    使用道具 舉報

    您需要登錄後才可以回帖 登錄 | 註冊

    本版積分規則

    Archiver|手機版|小黑屋|OK討論區

    GMT+8, 2024-5-15 06:06 AM , Processed in 0.056320 second(s), 17 queries , Gzip On.

    Powered by Discuz! X3.4

    Copyright © 2001-2020, Tencent Cloud.

    快速回復 返回頂部 返回列表