我正在尝试使用令牌在Scala中为SML编写解析器。它几乎按照我希望它的工作方式工作,除了当前解析
的事实让乐趣f x = r并且乐趣在r end;
而不是
让乐趣f x = r和g y in r end;
如何更改我的代码,使其识别出第二个函数不需要FunToken?
def parseDef:Def = {
currentToken match {
case ValToken => {
eat(ValToken);
val nme:String = currentToken match {
case IdToken(x) => {advance; x}
case _ => error("Expected a name after VAL.")
}
eat(EqualToken);
VAL(nme,parseExp)
}
case FunToken => {
eat(FunToken);
val fnme:String = currentToken match {
case IdToken(x) => {advance; x}
case _ => error("Expected a name after VAL.")
}
val xnme:String = currentToken match {
case IdToken(x) => {advance; x}
case _ => error("Expected a name after VAL.")
}
def parseAnd:Def = currentToken match {
case AndToken => {eat(AndToken); FUN(fnme,xnme,parseExp,parseAnd)}
case _ => NOFUN
}
FUN(fnme,xnme,parseExp,parseAnd)
}
case _ => error("Expected VAL or FUN.");
}
}
答案 0 :(得分:1)
只需实现正确的语法。而不是
@import "bootstrap-sprockets";
@import "bootstrap";
@import "jquery-ui/all";
@import "font-awesome";
@import "magnific-popup";
html,
body {
height: 100%;
width: 100%;
}
body {
font-family: 'Merriweather', 'Helvetica Neue', Arial, sans-serif;
}
hr {
border-color: #F05F40;
border-width: 3px;
max-width: 50px;
}
hr.light {
border-color: white;
}
a {
-webkit-transition: all 0.35s;
-moz-transition: all 0.35s;
transition: all 0.35s;
color: #F05F40;
}
a:hover,
a:focus {
color: #eb3812;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: 'Open Sans', 'Helvetica Neue', Arial, sans-serif;
}
p {
font-size: 16px;
line-height: 1.5;
margin-bottom: 20px;
}
.bg-primary {
background-color: #F05F40;
}
.bg-dark {
background-color: #222222;
color: white;
}
.text-faded {
color: rgba(255, 255, 255, 0.7);
}
section {
padding: 100px 0;
}
aside {
padding: 50px 0;
}
.no-padding {
padding: 0;
}
.navbar-default {
background-color: white;
border-color: rgba(34, 34, 34, 0.05);
font-family: 'Open Sans', 'Helvetica Neue', Arial, sans-serif;
-webkit-transition: all 0.35s;
-moz-transition: all 0.35s;
transition: all 0.35s;
}
.navbar-default .navbar-header .navbar-brand {
color: #F05F40;
font-family: 'Open Sans', 'Helvetica Neue', Arial, sans-serif;
font-weight: 700;
text-transform: uppercase;
}
.navbar-default .navbar-header .navbar-brand:hover,
.navbar-default .navbar-header .navbar-brand:focus {
color: #eb3812;
}
.navbar-default .navbar-header .navbar-toggle {
font-weight: 700;
font-size: 12px;
color: #222222;
text-transform: uppercase;
}
.navbar-default .nav > li > a,
.navbar-default .nav > li > a:focus {
text-transform: uppercase;
font-weight: 700;
font-size: 13px;
color: #222222;
}
.navbar-default .nav > li > a:hover,
.navbar-default .nav > li > a:focus:hover {
color: #F05F40;
}
.navbar-default .nav > li.active > a,
.navbar-default .nav > li.active > a:focus {
color: #F05F40 !important;
background-color: transparent;
}
.navbar-default .nav > li.active > a:hover,
.navbar-default .nav > li.active > a:focus:hover {
background-color: transparent;
}
@media (min-width: 768px) {
.navbar-default {
background-color: transparent;
border-color: rgba(255, 255, 255, 0.3);
}
.navbar-default .navbar-header .navbar-brand {
color: rgba(255, 255, 255, 0.7);
}
.navbar-default .navbar-header .navbar-brand:hover,
.navbar-default .navbar-header .navbar-brand:focus {
color: white;
}
.navbar-default .nav > li > a,
.navbar-default .nav > li > a:focus {
color: rgba(255, 255, 255, 0.7);
}
.navbar-default .nav > li > a:hover,
.navbar-default .nav > li > a:focus:hover {
color: white;
}
.navbar-default.affix {
background-color: white;
border-color: rgba(34, 34, 34, 0.05);
}
.navbar-default.affix .navbar-header .navbar-brand {
color: #F05F40;
font-size: 14px;
}
.navbar-default.affix .navbar-header .navbar-brand:hover,
.navbar-default.affix .navbar-header .navbar-brand:focus {
color: #eb3812;
}
.navbar-default.affix .nav > li > a,
.navbar-default.affix .nav > li > a:focus {
color: #222222;
}
.navbar-default.affix .nav > li > a:hover,
.navbar-default.affix .nav > li > a:focus:hover {
color: #F05F40;
}
}
header {
position: relative;
width: 100%;
min-height: auto;
-webkit-background-size: cover;
-moz-background-size: cover;
background-size: cover;
-o-background-size: cover;
background-position: center;
background-image: asset-data-url("header.jpg");
text-align: center;
color: white;
}
header .header-content {
position: relative;
text-align: center;
padding: 100px 15px 100px;
width: 100%;
}
header .header-content .header-content-inner h1 {
font-weight: 700;
text-transform: uppercase;
margin-top: 0;
margin-bottom: 0;
font-size: 30px;
}
header .header-content .header-content-inner hr {
margin: 30px auto;
}
header .header-content .header-content-inner p {
font-weight: 300;
color: rgba(255, 255, 255, 0.7);
font-size: 16px;
margin-bottom: 50px;
}
@media (min-width: 768px) {
header {
min-height: 100%;
}
header .header-content {
position: absolute;
top: 50%;
-webkit-transform: translateY(-50%);
-ms-transform: translateY(-50%);
transform: translateY(-50%);
padding: 0 50px;
}
header .header-content .header-content-inner {
max-width: 1000px;
margin-left: auto;
margin-right: auto;
}
header .header-content .header-content-inner h1 {
font-size: 50px;
}
header .header-content .header-content-inner p {
font-size: 18px;
max-width: 80%;
margin-left: auto;
margin-right: auto;
}
}
.section-heading {
margin-top: 0;
}
.service-box {
max-width: 400px;
margin: 50px auto 0;
}
@media (min-width: 992px) {
.service-box {
margin: 20px auto 0;
}
}
.service-box p {
margin-bottom: 0;
}
.portfolio-box {
position: relative;
display: block;
max-width: 650px;
margin: 0 auto;
}
.portfolio-box .portfolio-box-caption {
color: white;
opacity: 0;
display: block;
background: rgba(240, 95, 64, 0.9);
position: absolute;
bottom: 0;
text-align: center;
width: 100%;
height: 100%;
-webkit-transition: all 0.35s;
-moz-transition: all 0.35s;
transition: all 0.35s;
}
.portfolio-box .portfolio-box-caption .portfolio-box-caption-content {
width: 100%;
text-align: center;
position: absolute;
top: 50%;
transform: translateY(-50%);
}
.portfolio-box .portfolio-box-caption .portfolio-box-caption-content .project-category,
.portfolio-box .portfolio-box-caption .portfolio-box-caption-content .project-name {
font-family: 'Open Sans', 'Helvetica Neue', Arial, sans-serif;
padding: 0 15px;
}
.portfolio-box .portfolio-box-caption .portfolio-box-caption-content .project-category {
text-transform: uppercase;
font-weight: 600;
font-size: 14px;
}
.portfolio-box .portfolio-box-caption .portfolio-box-caption-content .project-name {
font-size: 18px;
}
.portfolio-box:hover .portfolio-box-caption {
opacity: 1;
}
.portfolio-box:focus {
outline: none;
}
@media (min-width: 768px) {
.portfolio-box .portfolio-box-caption .portfolio-box-caption-content .project-category {
font-size: 16px;
}
.portfolio-box .portfolio-box-caption .portfolio-box-caption-content .project-name {
font-size: 22px;
}
}
.call-to-action h2 {
margin: 0 auto 20px;
}
.text-primary {
color: #F05F40;
}
.no-gutter > [class*='col-'] {
padding-right: 0;
padding-left: 0;
}
.btn-default {
color: #222222;
background-color: white;
border-color: white;
-webkit-transition: all 0.35s;
-moz-transition: all 0.35s;
transition: all 0.35s;
}
.btn-default:hover,
.btn-default:focus,
.btn-default.focus,
.btn-default:active,
.btn-default.active,
.open > .dropdown-toggle.btn-default {
color: #222222;
background-color: #f2f2f2;
border-color: #ededed;
}
.btn-default:active,
.btn-default.active,
.open > .dropdown-toggle.btn-default {
background-image: none;
}
.btn-default.disabled,
.btn-default[disabled],
fieldset[disabled] .btn-default,
.btn-default.disabled:hover,
.btn-default[disabled]:hover,
fieldset[disabled] .btn-default:hover,
.btn-default.disabled:focus,
.btn-default[disabled]:focus,
fieldset[disabled] .btn-default:focus,
.btn-default.disabled.focus,
.btn-default[disabled].focus,
fieldset[disabled] .btn-default.focus,
.btn-default.disabled:active,
.btn-default[disabled]:active,
fieldset[disabled] .btn-default:active,
.btn-default.disabled.active,
.btn-default[disabled].active,
fieldset[disabled] .btn-default.active {
background-color: white;
border-color: white;
}
.btn-default .badge {
color: white;
background-color: #222222;
}
.btn-primary {
color: white;
background-color: #F05F40;
border-color: #F05F40;
-webkit-transition: all 0.35s;
-moz-transition: all 0.35s;
transition: all 0.35s;
}
.btn-primary:hover,
.btn-primary:focus,
.btn-primary.focus,
.btn-primary:active,
.btn-primary.active,
.open > .dropdown-toggle.btn-primary {
color: white;
background-color: #ee4b28;
border-color: #ed431f;
}
.btn-primary:active,
.btn-primary.active,
.open > .dropdown-toggle.btn-primary {
background-image: none;
}
.btn-primary.disabled,
.btn-primary[disabled],
fieldset[disabled] .btn-primary,
.btn-primary.disabled:hover,
.btn-primary[disabled]:hover,
fieldset[disabled] .btn-primary:hover,
.btn-primary.disabled:focus,
.btn-primary[disabled]:focus,
fieldset[disabled] .btn-primary:focus,
.btn-primary.disabled.focus,
.btn-primary[disabled].focus,
fieldset[disabled] .btn-primary.focus,
.btn-primary.disabled:active,
.btn-primary[disabled]:active,
fieldset[disabled] .btn-primary:active,
.btn-primary.disabled.active,
.btn-primary[disabled].active,
fieldset[disabled] .btn-primary.active {
background-color: #F05F40;
border-color: #F05F40;
}
.btn-primary .badge {
color: #F05F40;
background-color: white;
}
.btn {
font-family: 'Open Sans', 'Helvetica Neue', Arial, sans-serif;
border: none;
border-radius: 300px;
font-weight: 700;
text-transform: uppercase;
}
.btn-xl {
padding: 15px 30px;
}
::-moz-selection {
color: white;
text-shadow: none;
background: #222222;
}
::selection {
color: white;
text-shadow: none;
background: #222222;
}
img::selection {
color: white;
background: transparent;
}
img::-moz-selection {
color: white;
background: transparent;
}
body {
webkit-tap-highlight-color: #222222;
}
SML的语法实际上是
def ::= "val" id "=" exp | fun
fun ::= "fun" id id "=" exp ["and" fun]
顺便说一句,我认为解析好玩还有其他问题。 AFAICS,你没有在有趣的情况下解析任何“=”。而且,在“和”之后,你甚至不解析任何标识符,只是函数体。
答案 1 :(得分:0)
您可以使用" uneat"将FunToken注入您的输入流。功能。这不是最优雅的解决方案,但它是需要对当前代码进行最少修改的解决方案。
def parseAnd:Def = currentToken match {
case AndToken => { eat(AndToken);
uneat(FunToken);
FUN(fnme,xnme,parseExp,parseAnd) }
case _ => NOFUN
}